aboutsummaryrefslogtreecommitdiffstats
path: root/distrib/sdl-1.2.15/src/video
diff options
context:
space:
mode:
Diffstat (limited to 'distrib/sdl-1.2.15/src/video')
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_RLEaccel.c1941
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_RLEaccel_c.h31
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit.c360
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit.h528
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit_0.c471
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit_1.c523
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit_A.c2873
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_blit_N.c2492
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_bmp.c549
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_cursor.c758
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_cursor_c.h73
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_gamma.c233
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_glfuncs.h341
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_leaks.h31
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_pixels.c626
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_pixels_c.h46
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_stretch.c358
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_stretch_c.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_surface.c941
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_sysvideo.h439
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_video.c2041
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_yuv.c150
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_yuv_mmx.c428
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_yuv_sw.c1299
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_yuv_sw_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/SDL_yuvfuncs.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/README10
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/XME/xme.c410
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xinerama/Xinerama.c324
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xv/Xv.c1151
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xv/Xvlibint.h81
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c721
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA2.c993
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/Xxf86vm/XF86VMode.c1226
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/Xext.h50
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/Xinerama.h46
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/Xv.h129
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/Xvlib.h433
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/Xvproto.h604
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/extutil.h226
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXext.h52
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXproto.h192
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga.h265
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1.h169
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1str.h194
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dgastr.h344
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmode.h314
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmstr.h546
-rw-r--r--distrib/sdl-1.2.15/src/video/Xext/extensions/xme.h45
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents.c202
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse.c35
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.c388
-rw-r--r--distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.h66
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p.S452
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p_s.h75
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse.c159
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse_c.h42
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi.S42
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi_s.h54
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents.c234
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents_c.h52
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl.c1086
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl_c.h109
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarikeys.h140
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc.c52
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarisuper.h61
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents.c131
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents_c.h42
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents.c132
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents_c.h42
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents.c124
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents_c.h42
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt.S404
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt_s.h61
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents.c155
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents_c.h48
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt.S212
-rw-r--r--distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt_s.h52
-rw-r--r--distrib/sdl-1.2.15/src/video/blank_cursor.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_BView.h116
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_BWin.h290
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_lowvideo.h58
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents.cc415
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents_c.h31
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse.cc153
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysvideo.cc841
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm.cc92
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc314
-rw-r--r--distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.h73
-rw-r--r--distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents.c101
-rw-r--r--distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.c304
-rw-r--r--distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.h76
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcevents.c152
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcevents_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse.c35
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.c445
-rw-r--r--distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.h42
-rw-r--r--distrib/sdl-1.2.15/src/video/default_cursor.h116
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents.c163
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents_c.h28
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse.c35
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.c1101
-rw-r--r--distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.h124
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.c219
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_keys.h135
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.c1171
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.h62
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.c290
-rw-r--r--distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents.c45
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse.c33
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.c239
-rw-r--r--distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.h40
-rw-r--r--distrib/sdl-1.2.15/src/video/e_log.h140
-rw-r--r--distrib/sdl-1.2.15/src/video/e_pow.h302
-rw-r--r--distrib/sdl-1.2.15/src/video/e_sqrt.h493
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/3dfx_mmio.h56
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/3dfx_regs.h83
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.c215
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.c442
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.h55
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents.c1254
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents_c.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbkeys.h139
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.c280
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse.c33
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.c222
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.h36
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.c1982
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.h200
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/matrox_mmio.h51
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/matrox_regs.h376
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/riva_mmio.h449
-rw-r--r--distrib/sdl-1.2.15/src/video/fbcon/riva_regs.h43
-rw-r--r--distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.c1287
-rw-r--r--distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.h160
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemevents.c375
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemevents_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse.c205
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.c1337
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.h191
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemwm.c116
-rw-r--r--distrib/sdl-1.2.15/src/video/gem/SDL_gemwm_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents.c264
-rwxr-xr-xdistrib/sdl-1.2.15/src/video/ggi/SDL_ggievents_c.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/ggi/SDL_ggikeys.h135
-rw-r--r--distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse.c32
-rwxr-xr-xdistrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.c378
-rw-r--r--distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.h48
-rw-r--r--distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.c733
-rw-r--r--distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_lowvideo.h102
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents.c746
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl.c197
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl_c.h47
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_mackeys.h140
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse.c129
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm.c442
-rw-r--r--distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm_c.h41
-rw-r--r--distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.c1422
-rw-r--r--distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.h54
-rw-r--r--distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.c745
-rw-r--r--distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/math_private.h173
-rw-r--r--distrib/sdl-1.2.15/src/video/mmx.h704
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents.c382
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nximage.c230
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nximage_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes.c84
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse.c79
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse_c.h29
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.c544
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.h96
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm.c61
-rw-r--r--distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents.c83
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents_c.h51
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse.c34
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.c500
-rw-r--r--distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.h61
-rw-r--r--distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.c3018
-rw-r--r--distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.h71
-rw-r--r--distrib/sdl-1.2.15/src/video/os2fslib/SDL_vkeys.h74
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_events.c624
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_events_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.c406
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.h41
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_image.c1059
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_image_c.h59
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes.c390
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes_c.h43
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse.c220
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse_c.h39
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.c648
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.h157
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm.c118
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_phyuv.c504
-rw-r--r--distrib/sdl-1.2.15/src/video/photon/SDL_phyuv_c.h62
-rw-r--r--distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents.c117
-rw-r--r--distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.c364
-rw-r--r--distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.h50
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents.c977
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents_c.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gskeys.h139
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse.c146
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.c689
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.h95
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv.c461
-rw-r--r--distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events.c44
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events_c.h41
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.c621
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.h165
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv.c340
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv_c.h44
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/spulibs/Makefile83
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/spulibs/bilin_scaler.c2050
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/spulibs/fb_writer.c193
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/spulibs/spu_common.h108
-rw-r--r--distrib/sdl-1.2.15/src/video/ps3/spulibs/yuv2rgb_converter.c629
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.cc63
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.cc527
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.h110
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_lowvideo.h65
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents.cc269
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents_c.h31
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse.cc56
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_sysvideo.cc403
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm.cc35
-rw-r--r--distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm_c.h28
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/CGS.h84
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzEvents.m1063
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzGL.m292
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzKeys.h146
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h235
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m1695
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h28
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m574
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.h51
-rw-r--r--distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.m231
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S116
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c777
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c549
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c371
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h44
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c265
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c350
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h39
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c316
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h62
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c330
-rw-r--r--distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c501
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents.c412
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse.c33
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.c584
-rw-r--r--distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.h58
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocevents.cpp626
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.cpp1356
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocevents.cpp521
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.cpp594
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.h51
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa.cpp1505
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_new.cpp1443
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_old.cpp1075
-rw-r--r--distrib/sdl-1.2.15/src/video/symbian/SDL_epocevents_c.h60
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents.c299
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents_c.h155
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse.c56
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.c624
-rw-r--r--distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.h65
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_lowvideo.h152
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_sysevents.c855
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse.c259
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm.c297
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl.c659
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl_c.h135
-rw-r--r--distrib/sdl-1.2.15/src/video/wincommon/wmmsg.h1030
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_dibevents.c704
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_dibevents_c.h35
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c1499
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.h59
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_gapidibvideo.h56
-rw-r--r--distrib/sdl-1.2.15/src/video/windib/SDL_vkeys.h75
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events.c1005
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events_c.h37
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.c2537
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.h61
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv.c296
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv_c.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/windx5/directx.h97
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents.c233
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents_c.h36
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse.c33
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse_c.h26
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.c609
-rw-r--r--distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.h76
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11dga.c90
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11dga_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c223
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.h93
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11events.c1414
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11events_c.h34
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma.c142
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma_c.h32
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11gl.c577
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11gl_c.h99
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11image.c316
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11image_c.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11modes.c1143
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11modes_c.h43
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse.c288
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse_c.h33
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h211
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c1580
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h217
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c620
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h38
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv.c538
-rw-r--r--distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv_c.h41
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.c1116
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.h111
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.c77
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.h86
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.c104
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.h114
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.c106
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.h129
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.c83
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.h82
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.c63
-rw-r--r--distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.h64
364 files changed, 114002 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.15/src/video/SDL_RLEaccel.c b/distrib/sdl-1.2.15/src/video/SDL_RLEaccel.c
new file mode 100644
index 0000000..d4b191c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_RLEaccel.c
@@ -0,0 +1,1941 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * RLE encoding for software colorkey and alpha-channel acceleration
+ *
+ * Original version by Sam Lantinga
+ *
+ * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and
+ * decoder. Added per-surface alpha blitter. Added per-pixel alpha
+ * format, encoder and blitter.
+ *
+ * Many thanks to Xark and johns for hints, benchmarks and useful comments
+ * leading to this code.
+ *
+ * Welcome to Macro Mayhem.
+ */
+
+/*
+ * The encoding translates the image data to a stream of segments of the form
+ *
+ * <skip> <run> <data>
+ *
+ * where <skip> is the number of transparent pixels to skip,
+ * <run> is the number of opaque pixels to blit,
+ * and <data> are the pixels themselves.
+ *
+ * This basic structure is used both for colorkeyed surfaces, used for simple
+ * binary transparency and for per-surface alpha blending, and for surfaces
+ * with per-pixel alpha. The details differ, however:
+ *
+ * Encoding of colorkeyed surfaces:
+ *
+ * Encoded pixels always have the same format as the target surface.
+ * <skip> and <run> are unsigned 8 bit integers, except for 32 bit depth
+ * where they are 16 bit. This makes the pixel data aligned at all times.
+ * Segments never wrap around from one scan line to the next.
+ *
+ * The end of the sequence is marked by a zero <skip>,<run> pair at the *
+ * beginning of a line.
+ *
+ * Encoding of surfaces with per-pixel alpha:
+ *
+ * The sequence begins with a struct RLEDestFormat describing the target
+ * pixel format, to provide reliable un-encoding.
+ *
+ * Each scan line is encoded twice: First all completely opaque pixels,
+ * encoded in the target format as described above, and then all
+ * partially transparent (translucent) pixels (where 1 <= alpha <= 254),
+ * in the following 32-bit format:
+ *
+ * For 32-bit targets, each pixel has the target RGB format but with
+ * the alpha value occupying the highest 8 bits. The <skip> and <run>
+ * counts are 16 bit.
+ *
+ * For 16-bit targets, each pixel has the target RGB format, but with
+ * the middle component (usually green) shifted 16 steps to the left,
+ * and the hole filled with the 5 most significant bits of the alpha value.
+ * i.e. if the target has the format rrrrrggggggbbbbb,
+ * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb.
+ * The <skip> and <run> counts are 8 bit for the opaque lines, 16 bit
+ * for the translucent lines. Two padding bytes may be inserted
+ * before each translucent line to keep them 32-bit aligned.
+ *
+ * The end of the sequence is marked by a zero <skip>,<run> pair at the
+ * beginning of an opaque line.
+ */
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_RLEaccel_c.h"
+
+/* Force MMX to 0; this blows up on almost every major compiler now. --ryan. */
+#if 0 && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES
+#define MMX_ASMBLIT
+#endif
+
+#ifdef MMX_ASMBLIT
+#include "mmx.h"
+#include "SDL_cpuinfo.h"
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define PIXEL_COPY(to, from, len, bpp) \
+do { \
+ if(bpp == 4) { \
+ SDL_memcpy4(to, from, (size_t)(len)); \
+ } else { \
+ SDL_memcpy(to, from, (size_t)(len) * (bpp)); \
+ } \
+} while(0)
+
+/*
+ * Various colorkey blit methods, for opaque and per-surface alpha
+ */
+
+#define OPAQUE_BLIT(to, from, length, bpp, alpha) \
+ PIXEL_COPY(to, from, length, bpp)
+
+#ifdef MMX_ASMBLIT
+
+#define ALPHA_BLIT32_888MMX(to, from, length, bpp, alpha) \
+ do { \
+ Uint32 *srcp = (Uint32 *)(from); \
+ Uint32 *dstp = (Uint32 *)(to); \
+ int i = 0x00FF00FF; \
+ movd_m2r(*(&i), mm3); \
+ punpckldq_r2r(mm3, mm3); \
+ i = 0xFF000000; \
+ movd_m2r(*(&i), mm7); \
+ punpckldq_r2r(mm7, mm7); \
+ i = alpha | alpha << 16; \
+ movd_m2r(*(&i), mm4); \
+ punpckldq_r2r(mm4, mm4); \
+ pcmpeqd_r2r(mm5,mm5); /* set mm5 to "1" */ \
+ pxor_r2r(mm7, mm5); /* make clear alpha mask */ \
+ i = length; \
+ if(i & 1) { \
+ movd_m2r((*srcp), mm1); /* src -> mm1 */ \
+ punpcklbw_r2r(mm1, mm1); \
+ pand_r2r(mm3, mm1); \
+ movd_m2r((*dstp), mm2); /* dst -> mm2 */ \
+ punpcklbw_r2r(mm2, mm2); \
+ pand_r2r(mm3, mm2); \
+ psubw_r2r(mm2, mm1); \
+ pmullw_r2r(mm4, mm1); \
+ psrlw_i2r(8, mm1); \
+ paddw_r2r(mm1, mm2); \
+ pand_r2r(mm3, mm2); \
+ packuswb_r2r(mm2, mm2); \
+ pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \
+ movd_r2m(mm2, *dstp); \
+ ++srcp; \
+ ++dstp; \
+ i--; \
+ } \
+ for(; i > 0; --i) { \
+ movq_m2r((*srcp), mm0); \
+ movq_r2r(mm0, mm1); \
+ punpcklbw_r2r(mm0, mm0); \
+ movq_m2r((*dstp), mm2); \
+ punpckhbw_r2r(mm1, mm1); \
+ movq_r2r(mm2, mm6); \
+ pand_r2r(mm3, mm0); \
+ punpcklbw_r2r(mm2, mm2); \
+ pand_r2r(mm3, mm1); \
+ punpckhbw_r2r(mm6, mm6); \
+ pand_r2r(mm3, mm2); \
+ psubw_r2r(mm2, mm0); \
+ pmullw_r2r(mm4, mm0); \
+ pand_r2r(mm3, mm6); \
+ psubw_r2r(mm6, mm1); \
+ pmullw_r2r(mm4, mm1); \
+ psrlw_i2r(8, mm0); \
+ paddw_r2r(mm0, mm2); \
+ psrlw_i2r(8, mm1); \
+ paddw_r2r(mm1, mm6); \
+ pand_r2r(mm3, mm2); \
+ pand_r2r(mm3, mm6); \
+ packuswb_r2r(mm2, mm2); \
+ packuswb_r2r(mm6, mm6); \
+ psrlq_i2r(32, mm2); \
+ psllq_i2r(32, mm6); \
+ por_r2r(mm6, mm2); \
+ pand_r2r(mm5, mm2); /* 00000RGB -> mm2 */ \
+ movq_r2m(mm2, *dstp); \
+ srcp += 2; \
+ dstp += 2; \
+ i--; \
+ } \
+ emms(); \
+ } while(0)
+
+#define ALPHA_BLIT16_565MMX(to, from, length, bpp, alpha) \
+ do { \
+ int i, n = 0; \
+ Uint16 *srcp = (Uint16 *)(from); \
+ Uint16 *dstp = (Uint16 *)(to); \
+ Uint32 ALPHA = 0xF800; \
+ movd_m2r(*(&ALPHA), mm1); \
+ punpcklwd_r2r(mm1, mm1); \
+ punpcklwd_r2r(mm1, mm1); \
+ ALPHA = 0x07E0; \
+ movd_m2r(*(&ALPHA), mm4); \
+ punpcklwd_r2r(mm4, mm4); \
+ punpcklwd_r2r(mm4, mm4); \
+ ALPHA = 0x001F; \
+ movd_m2r(*(&ALPHA), mm7); \
+ punpcklwd_r2r(mm7, mm7); \
+ punpcklwd_r2r(mm7, mm7); \
+ alpha &= ~(1+2+4); \
+ i = (Uint32)alpha | (Uint32)alpha << 16; \
+ movd_m2r(*(&i), mm0); \
+ punpckldq_r2r(mm0, mm0); \
+ ALPHA = alpha >> 3; \
+ i = ((int)(length) & 3); \
+ for(; i > 0; --i) { \
+ Uint32 s = *srcp++; \
+ Uint32 d = *dstp; \
+ s = (s | s << 16) & 0x07e0f81f; \
+ d = (d | d << 16) & 0x07e0f81f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x07e0f81f; \
+ *dstp++ = d | d >> 16; \
+ n++; \
+ } \
+ i = (int)(length) - n; \
+ for(; i > 0; --i) { \
+ movq_m2r((*dstp), mm3); \
+ movq_m2r((*srcp), mm2); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm1 , mm5); \
+ psrlq_i2r(11, mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm1 , mm6); \
+ psrlq_i2r(11, mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ psllq_i2r(11, mm6); \
+ pand_r2r(mm1, mm6); \
+ movq_r2r(mm4, mm5); \
+ por_r2r(mm7, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm4 , mm5); \
+ psrlq_i2r(5, mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm4 , mm6); \
+ psrlq_i2r(5, mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ psllq_i2r(5, mm6); \
+ pand_r2r(mm4, mm6); \
+ movq_r2r(mm1, mm5); \
+ por_r2r(mm7, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm7 , mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm7 , mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ pand_r2r(mm7, mm6); \
+ movq_r2r(mm1, mm5); \
+ por_r2r(mm4, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2m(mm3, *dstp); \
+ srcp += 4; \
+ dstp += 4; \
+ i -= 3; \
+ } \
+ emms(); \
+ } while(0)
+
+#define ALPHA_BLIT16_555MMX(to, from, length, bpp, alpha) \
+ do { \
+ int i, n = 0; \
+ Uint16 *srcp = (Uint16 *)(from); \
+ Uint16 *dstp = (Uint16 *)(to); \
+ Uint32 ALPHA = 0x7C00; \
+ movd_m2r(*(&ALPHA), mm1); \
+ punpcklwd_r2r(mm1, mm1); \
+ punpcklwd_r2r(mm1, mm1); \
+ ALPHA = 0x03E0; \
+ movd_m2r(*(&ALPHA), mm4); \
+ punpcklwd_r2r(mm4, mm4); \
+ punpcklwd_r2r(mm4, mm4); \
+ ALPHA = 0x001F; \
+ movd_m2r(*(&ALPHA), mm7); \
+ punpcklwd_r2r(mm7, mm7); \
+ punpcklwd_r2r(mm7, mm7); \
+ alpha &= ~(1+2+4); \
+ i = (Uint32)alpha | (Uint32)alpha << 16; \
+ movd_m2r(*(&i), mm0); \
+ punpckldq_r2r(mm0, mm0); \
+ i = ((int)(length) & 3); \
+ ALPHA = alpha >> 3; \
+ for(; i > 0; --i) { \
+ Uint32 s = *srcp++; \
+ Uint32 d = *dstp; \
+ s = (s | s << 16) & 0x03e07c1f; \
+ d = (d | d << 16) & 0x03e07c1f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x03e07c1f; \
+ *dstp++ = d | d >> 16; \
+ n++; \
+ } \
+ i = (int)(length) - n; \
+ for(; i > 0; --i) { \
+ movq_m2r((*dstp), mm3); \
+ movq_m2r((*srcp), mm2); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm1 , mm5); \
+ psrlq_i2r(10, mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm1 , mm6); \
+ psrlq_i2r(10, mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ psllq_i2r(10, mm6); \
+ pand_r2r(mm1, mm6); \
+ movq_r2r(mm4, mm5); \
+ por_r2r(mm7, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm4 , mm5); \
+ psrlq_i2r(5, mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm4 , mm6); \
+ psrlq_i2r(5, mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ psllq_i2r(5, mm6); \
+ pand_r2r(mm4, mm6); \
+ movq_r2r(mm1, mm5); \
+ por_r2r(mm7, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2r(mm2, mm5); \
+ pand_r2r(mm7 , mm5); \
+ movq_r2r(mm3, mm6); \
+ pand_r2r(mm7 , mm6); \
+ psubw_r2r(mm6, mm5); \
+ pmullw_r2r(mm0, mm5); \
+ psrlw_i2r(8, mm5); \
+ paddw_r2r(mm5, mm6); \
+ pand_r2r(mm7, mm6); \
+ movq_r2r(mm1, mm5); \
+ por_r2r(mm4, mm5); \
+ pand_r2r(mm5, mm3); \
+ por_r2r(mm6, mm3); \
+ movq_r2m(mm3, *dstp); \
+ srcp += 4; \
+ dstp += 4; \
+ i -= 3; \
+ } \
+ emms(); \
+ } while(0)
+
+#endif
+
+/*
+ * For 32bpp pixels on the form 0x00rrggbb:
+ * If we treat the middle component separately, we can process the two
+ * remaining in parallel. This is safe to do because of the gap to the left
+ * of each component, so the bits from the multiplication don't collide.
+ * This can be used for any RGB permutation of course.
+ */
+#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint32 *src = (Uint32 *)(from); \
+ Uint32 *dst = (Uint32 *)(to); \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ Uint32 s1 = s & 0xff00ff; \
+ Uint32 d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ *dst++ = d1 | d; \
+ } \
+ } while(0)
+
+/*
+ * For 16bpp pixels we can go a step further: put the middle component
+ * in the high 16 bits of a 32 bit word, and process all three RGB
+ * components at the same time. Since the smallest gap is here just
+ * 5 bits, we have to scale alpha down to 5 bits as well.
+ */
+#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ Uint32 ALPHA = alpha >> 3; \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ s = (s | s << 16) & 0x07e0f81f; \
+ d = (d | d << 16) & 0x07e0f81f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x07e0f81f; \
+ *dst++ = (Uint16)(d | d >> 16); \
+ } \
+ } while(0)
+
+#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ Uint32 ALPHA = alpha >> 3; \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ s = (s | s << 16) & 0x03e07c1f; \
+ d = (d | d << 16) & 0x03e07c1f; \
+ d += (s - d) * ALPHA >> 5; \
+ d &= 0x03e07c1f; \
+ *dst++ = (Uint16)(d | d >> 16); \
+ } \
+ } while(0)
+
+/*
+ * The general slow catch-all function, for remaining depths and formats
+ */
+#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint8 *src = from; \
+ Uint8 *dst = to; \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s, d; \
+ unsigned rs, gs, bs, rd, gd, bd; \
+ switch(bpp) { \
+ case 2: \
+ s = *(Uint16 *)src; \
+ d = *(Uint16 *)dst; \
+ break; \
+ case 3: \
+ if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \
+ s = (src[0] << 16) | (src[1] << 8) | src[2]; \
+ d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \
+ } else { \
+ s = (src[2] << 16) | (src[1] << 8) | src[0]; \
+ d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \
+ } \
+ break; \
+ case 4: \
+ s = *(Uint32 *)src; \
+ d = *(Uint32 *)dst; \
+ break; \
+ } \
+ RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \
+ RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \
+ rd += (rs - rd) * alpha >> 8; \
+ gd += (gs - gd) * alpha >> 8; \
+ bd += (bs - bd) * alpha >> 8; \
+ PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \
+ switch(bpp) { \
+ case 2: \
+ *(Uint16 *)dst = (Uint16)d; \
+ break; \
+ case 3: \
+ if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \
+ dst[0] = (Uint8)(d >> 16); \
+ dst[1] = (Uint8)(d >> 8); \
+ dst[2] = (Uint8)(d); \
+ } else { \
+ dst[0] = (Uint8)d; \
+ dst[1] = (Uint8)(d >> 8); \
+ dst[2] = (Uint8)(d >> 16); \
+ } \
+ break; \
+ case 4: \
+ *(Uint32 *)dst = d; \
+ break; \
+ } \
+ src += bpp; \
+ dst += bpp; \
+ } \
+ } while(0)
+
+#ifdef MMX_ASMBLIT
+
+#define ALPHA_BLIT32_888_50MMX(to, from, length, bpp, alpha) \
+ do { \
+ Uint32 *srcp = (Uint32 *)(from); \
+ Uint32 *dstp = (Uint32 *)(to); \
+ int i = 0x00fefefe; \
+ movd_m2r(*(&i), mm4); \
+ punpckldq_r2r(mm4, mm4); \
+ i = 0x00010101; \
+ movd_m2r(*(&i), mm3); \
+ punpckldq_r2r(mm3, mm3); \
+ i = (int)(length); \
+ if( i & 1 ) { \
+ Uint32 s = *srcp++; \
+ Uint32 d = *dstp; \
+ *dstp++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \
+ + (s & d & 0x00010101); \
+ i--; \
+ } \
+ for(; i > 0; --i) { \
+ movq_m2r((*dstp), mm2); /* dst -> mm2 */ \
+ movq_r2r(mm2, mm6); /* dst -> mm6 */ \
+ movq_m2r((*srcp), mm1); /* src -> mm1 */ \
+ movq_r2r(mm1, mm5); /* src -> mm5 */ \
+ pand_r2r(mm4, mm6); /* dst & 0x00fefefe -> mm6 */ \
+ pand_r2r(mm4, mm5); /* src & 0x00fefefe -> mm5 */ \
+ paddd_r2r(mm6, mm5); /* (dst & 0x00fefefe) + (dst & 0x00fefefe) -> mm5 */ \
+ psrld_i2r(1, mm5); \
+ pand_r2r(mm1, mm2); /* s & d -> mm2 */ \
+ pand_r2r(mm3, mm2); /* s & d & 0x00010101 -> mm2 */ \
+ paddd_r2r(mm5, mm2); \
+ movq_r2m(mm2, (*dstp)); \
+ dstp += 2; \
+ srcp += 2; \
+ i--; \
+ } \
+ emms(); \
+ } while(0)
+
+#endif
+
+/*
+ * Special case: 50% alpha (alpha=128)
+ * This is treated specially because it can be optimized very well, and
+ * since it is good for many cases of semi-translucency.
+ * The theory is to do all three components at the same time:
+ * First zero the lowest bit of each component, which gives us room to
+ * add them. Then shift right and add the sum of the lowest bits.
+ */
+#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \
+ do { \
+ int i; \
+ Uint32 *src = (Uint32 *)(from); \
+ Uint32 *dst = (Uint32 *)(to); \
+ for(i = 0; i < (int)(length); i++) { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \
+ + (s & d & 0x00010101); \
+ } \
+ } while(0)
+
+/*
+ * For 16bpp, we can actually blend two pixels in parallel, if we take
+ * care to shift before we add, not after.
+ */
+
+/* helper: blend a single 16 bit pixel at 50% */
+#define BLEND16_50(dst, src, mask) \
+ do { \
+ Uint32 s = *src++; \
+ Uint32 d = *dst; \
+ *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \
+ (s & d & (~mask & 0xffff))); \
+ } while(0)
+
+/* basic 16bpp blender. mask is the pixels to keep when adding. */
+#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \
+ do { \
+ unsigned n = (length); \
+ Uint16 *src = (Uint16 *)(from); \
+ Uint16 *dst = (Uint16 *)(to); \
+ if(((uintptr_t)src ^ (uintptr_t)dst) & 3) { \
+ /* source and destination not in phase, blit one by one */ \
+ while(n--) \
+ BLEND16_50(dst, src, mask); \
+ } else { \
+ if((uintptr_t)src & 3) { \
+ /* first odd pixel */ \
+ BLEND16_50(dst, src, mask); \
+ n--; \
+ } \
+ for(; n > 1; n -= 2) { \
+ Uint32 s = *(Uint32 *)src; \
+ Uint32 d = *(Uint32 *)dst; \
+ *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \
+ + ((d & (mask | mask << 16)) >> 1) \
+ + (s & d & (~(mask | mask << 16))); \
+ src += 2; \
+ dst += 2; \
+ } \
+ if(n) \
+ BLEND16_50(dst, src, mask); /* last odd pixel */ \
+ } \
+ } while(0)
+
+#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \
+ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de)
+
+#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \
+ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde)
+
+#ifdef MMX_ASMBLIT
+
+#define CHOOSE_BLIT(blitter, alpha, fmt) \
+ do { \
+ if(alpha == 255) { \
+ switch(fmt->BytesPerPixel) { \
+ case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \
+ case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \
+ case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \
+ case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \
+ } \
+ } else { \
+ switch(fmt->BytesPerPixel) { \
+ case 1: \
+ /* No 8bpp alpha blitting */ \
+ break; \
+ \
+ case 2: \
+ switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \
+ case 0xffff: \
+ if(fmt->Gmask == 0x07e0 \
+ || fmt->Rmask == 0x07e0 \
+ || fmt->Bmask == 0x07e0) { \
+ if(alpha == 128) \
+ blitter(2, Uint8, ALPHA_BLIT16_565_50); \
+ else { \
+ if(SDL_HasMMX()) \
+ blitter(2, Uint8, ALPHA_BLIT16_565MMX); \
+ else \
+ blitter(2, Uint8, ALPHA_BLIT16_565); \
+ } \
+ } else \
+ goto general16; \
+ break; \
+ \
+ case 0x7fff: \
+ if(fmt->Gmask == 0x03e0 \
+ || fmt->Rmask == 0x03e0 \
+ || fmt->Bmask == 0x03e0) { \
+ if(alpha == 128) \
+ blitter(2, Uint8, ALPHA_BLIT16_555_50); \
+ else { \
+ if(SDL_HasMMX()) \
+ blitter(2, Uint8, ALPHA_BLIT16_555MMX); \
+ else \
+ blitter(2, Uint8, ALPHA_BLIT16_555); \
+ } \
+ break; \
+ } \
+ /* fallthrough */ \
+ \
+ default: \
+ general16: \
+ blitter(2, Uint8, ALPHA_BLIT_ANY); \
+ } \
+ break; \
+ \
+ case 3: \
+ blitter(3, Uint8, ALPHA_BLIT_ANY); \
+ break; \
+ \
+ case 4: \
+ if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \
+ && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \
+ || fmt->Bmask == 0xff00)) { \
+ if(alpha == 128) \
+ { \
+ if(SDL_HasMMX()) \
+ blitter(4, Uint16, ALPHA_BLIT32_888_50MMX);\
+ else \
+ blitter(4, Uint16, ALPHA_BLIT32_888_50);\
+ } \
+ else \
+ { \
+ if(SDL_HasMMX()) \
+ blitter(4, Uint16, ALPHA_BLIT32_888MMX);\
+ else \
+ blitter(4, Uint16, ALPHA_BLIT32_888); \
+ } \
+ } else \
+ blitter(4, Uint16, ALPHA_BLIT_ANY); \
+ break; \
+ } \
+ } \
+ } while(0)
+
+#else
+
+#define CHOOSE_BLIT(blitter, alpha, fmt) \
+ do { \
+ if(alpha == 255) { \
+ switch(fmt->BytesPerPixel) { \
+ case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \
+ case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \
+ case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \
+ case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \
+ } \
+ } else { \
+ switch(fmt->BytesPerPixel) { \
+ case 1: \
+ /* No 8bpp alpha blitting */ \
+ break; \
+ \
+ case 2: \
+ switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \
+ case 0xffff: \
+ if(fmt->Gmask == 0x07e0 \
+ || fmt->Rmask == 0x07e0 \
+ || fmt->Bmask == 0x07e0) { \
+ if(alpha == 128) \
+ blitter(2, Uint8, ALPHA_BLIT16_565_50); \
+ else { \
+ blitter(2, Uint8, ALPHA_BLIT16_565); \
+ } \
+ } else \
+ goto general16; \
+ break; \
+ \
+ case 0x7fff: \
+ if(fmt->Gmask == 0x03e0 \
+ || fmt->Rmask == 0x03e0 \
+ || fmt->Bmask == 0x03e0) { \
+ if(alpha == 128) \
+ blitter(2, Uint8, ALPHA_BLIT16_555_50); \
+ else { \
+ blitter(2, Uint8, ALPHA_BLIT16_555); \
+ } \
+ break; \
+ } \
+ /* fallthrough */ \
+ \
+ default: \
+ general16: \
+ blitter(2, Uint8, ALPHA_BLIT_ANY); \
+ } \
+ break; \
+ \
+ case 3: \
+ blitter(3, Uint8, ALPHA_BLIT_ANY); \
+ break; \
+ \
+ case 4: \
+ if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \
+ && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \
+ || fmt->Bmask == 0xff00)) { \
+ if(alpha == 128) \
+ blitter(4, Uint16, ALPHA_BLIT32_888_50); \
+ else \
+ blitter(4, Uint16, ALPHA_BLIT32_888); \
+ } else \
+ blitter(4, Uint16, ALPHA_BLIT_ANY); \
+ break; \
+ } \
+ } \
+ } while(0)
+
+#endif
+
+/*
+ * This takes care of the case when the surface is clipped on the left and/or
+ * right. Top clipping has already been taken care of.
+ */
+static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst,
+ Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha)
+{
+ SDL_PixelFormat *fmt = dst->format;
+
+#define RLECLIPBLIT(bpp, Type, do_blit) \
+ do { \
+ int linecount = srcrect->h; \
+ int ofs = 0; \
+ int left = srcrect->x; \
+ int right = left + srcrect->w; \
+ dstbuf -= left * bpp; \
+ for(;;) { \
+ int run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Type); \
+ if(run) { \
+ /* clip to left and right borders */ \
+ if(ofs < right) { \
+ int start = 0; \
+ int len = run; \
+ int startcol; \
+ if(left - ofs > 0) { \
+ start = left - ofs; \
+ len -= start; \
+ if(len <= 0) \
+ goto nocopy ## bpp ## do_blit; \
+ } \
+ startcol = ofs + start; \
+ if(len > right - startcol) \
+ len = right - startcol; \
+ do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \
+ len, bpp, alpha); \
+ } \
+ nocopy ## bpp ## do_blit: \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if(!ofs) \
+ break; \
+ if(ofs == w) { \
+ ofs = 0; \
+ dstbuf += dst->pitch; \
+ if(!--linecount) \
+ break; \
+ } \
+ } \
+ } while(0)
+
+ CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt);
+
+#undef RLECLIPBLIT
+
+}
+
+
+/* blit a colorkeyed RLE surface */
+int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ Uint8 *dstbuf;
+ Uint8 *srcbuf;
+ int x, y;
+ int w = src->w;
+ unsigned alpha;
+
+ /* Lock the destination if necessary */
+ if ( SDL_MUSTLOCK(dst) ) {
+ if ( SDL_LockSurface(dst) < 0 ) {
+ return(-1);
+ }
+ }
+
+ /* Set up the source and destination pointers */
+ x = dstrect->x;
+ y = dstrect->y;
+ dstbuf = (Uint8 *)dst->pixels
+ + y * dst->pitch + x * src->format->BytesPerPixel;
+ srcbuf = (Uint8 *)src->map->sw_data->aux_data;
+
+ {
+ /* skip lines at the top if neccessary */
+ int vskip = srcrect->y;
+ int ofs = 0;
+ if(vskip) {
+
+#define RLESKIP(bpp, Type) \
+ for(;;) { \
+ int run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += sizeof(Type) * 2; \
+ if(run) { \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if(!ofs) \
+ goto done; \
+ if(ofs == w) { \
+ ofs = 0; \
+ if(!--vskip) \
+ break; \
+ } \
+ }
+
+ switch(src->format->BytesPerPixel) {
+ case 1: RLESKIP(1, Uint8); break;
+ case 2: RLESKIP(2, Uint8); break;
+ case 3: RLESKIP(3, Uint8); break;
+ case 4: RLESKIP(4, Uint16); break;
+ }
+
+#undef RLESKIP
+
+ }
+ }
+
+ alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA
+ ? src->format->alpha : 255;
+ /* if left or right edge clipping needed, call clip blit */
+ if ( srcrect->x || srcrect->w != src->w ) {
+ RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
+ } else {
+ SDL_PixelFormat *fmt = src->format;
+
+#define RLEBLIT(bpp, Type, do_blit) \
+ do { \
+ int linecount = srcrect->h; \
+ int ofs = 0; \
+ for(;;) { \
+ unsigned run; \
+ ofs += *(Type *)srcbuf; \
+ run = ((Type *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Type); \
+ if(run) { \
+ do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \
+ srcbuf += run * bpp; \
+ ofs += run; \
+ } else if(!ofs) \
+ break; \
+ if(ofs == w) { \
+ ofs = 0; \
+ dstbuf += dst->pitch; \
+ if(!--linecount) \
+ break; \
+ } \
+ } \
+ } while(0)
+
+ CHOOSE_BLIT(RLEBLIT, alpha, fmt);
+
+#undef RLEBLIT
+ }
+
+done:
+ /* Unlock the destination if necessary */
+ if ( SDL_MUSTLOCK(dst) ) {
+ SDL_UnlockSurface(dst);
+ }
+ return(0);
+}
+
+#undef OPAQUE_BLIT
+
+/*
+ * Per-pixel blitting macros for translucent pixels:
+ * These use the same techniques as the per-surface blitting macros
+ */
+
+/*
+ * For 32bpp pixels, we have made sure the alpha is stored in the top
+ * 8 bits, so proceed as usual
+ */
+#define BLIT_TRANSL_888(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = s >> 24; \
+ Uint32 s1 = s & 0xff00ff; \
+ Uint32 d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ dst = d1 | d; \
+ } while(0)
+
+/*
+ * For 16bpp pixels, we have stored the 5 most significant alpha bits in
+ * bits 5-10. As before, we can process all 3 RGB components at the same time.
+ */
+#define BLIT_TRANSL_565(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = (s & 0x3e0) >> 5; \
+ s &= 0x07e0f81f; \
+ d = (d | d << 16) & 0x07e0f81f; \
+ d += (s - d) * alpha >> 5; \
+ d &= 0x07e0f81f; \
+ dst = (Uint16)(d | d >> 16); \
+ } while(0)
+
+#define BLIT_TRANSL_555(src, dst) \
+ do { \
+ Uint32 s = src; \
+ Uint32 d = dst; \
+ unsigned alpha = (s & 0x3e0) >> 5; \
+ s &= 0x03e07c1f; \
+ d = (d | d << 16) & 0x03e07c1f; \
+ d += (s - d) * alpha >> 5; \
+ d &= 0x03e07c1f; \
+ dst = (Uint16)(d | d >> 16); \
+ } while(0)
+
+/* used to save the destination format in the encoding. Designed to be
+ macro-compatible with SDL_PixelFormat but without the unneeded fields */
+typedef struct {
+ Uint8 BytesPerPixel;
+ Uint8 Rloss;
+ Uint8 Gloss;
+ Uint8 Bloss;
+ Uint8 Rshift;
+ Uint8 Gshift;
+ Uint8 Bshift;
+ Uint8 Ashift;
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ Uint32 Amask;
+} RLEDestFormat;
+
+/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */
+static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst,
+ Uint8 *dstbuf, SDL_Rect *srcrect)
+{
+ SDL_PixelFormat *df = dst->format;
+ /*
+ * clipped blitter: Ptype is the destination pixel type,
+ * Ctype the translucent count type, and do_blend the macro
+ * to blend one pixel.
+ */
+#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \
+ do { \
+ int linecount = srcrect->h; \
+ int left = srcrect->x; \
+ int right = left + srcrect->w; \
+ dstbuf -= left * sizeof(Ptype); \
+ do { \
+ int ofs = 0; \
+ /* blit opaque pixels on one line */ \
+ do { \
+ unsigned run; \
+ ofs += ((Ctype *)srcbuf)[0]; \
+ run = ((Ctype *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Ctype); \
+ if(run) { \
+ /* clip to left and right borders */ \
+ int cofs = ofs; \
+ int crun = run; \
+ if(left - cofs > 0) { \
+ crun -= left - cofs; \
+ cofs = left; \
+ } \
+ if(crun > right - cofs) \
+ crun = right - cofs; \
+ if(crun > 0) \
+ PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \
+ srcbuf + (cofs - ofs) * sizeof(Ptype), \
+ (unsigned)crun, sizeof(Ptype)); \
+ srcbuf += run * sizeof(Ptype); \
+ ofs += run; \
+ } else if(!ofs) \
+ return; \
+ } while(ofs < w); \
+ /* skip padding if necessary */ \
+ if(sizeof(Ptype) == 2) \
+ srcbuf += (uintptr_t)srcbuf & 2; \
+ /* blit translucent pixels on the same line */ \
+ ofs = 0; \
+ do { \
+ unsigned run; \
+ ofs += ((Uint16 *)srcbuf)[0]; \
+ run = ((Uint16 *)srcbuf)[1]; \
+ srcbuf += 4; \
+ if(run) { \
+ /* clip to left and right borders */ \
+ int cofs = ofs; \
+ int crun = run; \
+ if(left - cofs > 0) { \
+ crun -= left - cofs; \
+ cofs = left; \
+ } \
+ if(crun > right - cofs) \
+ crun = right - cofs; \
+ if(crun > 0) { \
+ Ptype *dst = (Ptype *)dstbuf + cofs; \
+ Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \
+ int i; \
+ for(i = 0; i < crun; i++) \
+ do_blend(src[i], dst[i]); \
+ } \
+ srcbuf += run * 4; \
+ ofs += run; \
+ } \
+ } while(ofs < w); \
+ dstbuf += dst->pitch; \
+ } while(--linecount); \
+ } while(0)
+
+ switch(df->BytesPerPixel) {
+ case 2:
+ if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0
+ || df->Bmask == 0x07e0)
+ RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565);
+ else
+ RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555);
+ break;
+ case 4:
+ RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888);
+ break;
+ }
+}
+
+/* blit a pixel-alpha RLE surface */
+int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int x, y;
+ int w = src->w;
+ Uint8 *srcbuf, *dstbuf;
+ SDL_PixelFormat *df = dst->format;
+
+ /* Lock the destination if necessary */
+ if ( SDL_MUSTLOCK(dst) ) {
+ if ( SDL_LockSurface(dst) < 0 ) {
+ return -1;
+ }
+ }
+
+ x = dstrect->x;
+ y = dstrect->y;
+ dstbuf = (Uint8 *)dst->pixels
+ + y * dst->pitch + x * df->BytesPerPixel;
+ srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat);
+
+ {
+ /* skip lines at the top if necessary */
+ int vskip = srcrect->y;
+ if(vskip) {
+ int ofs;
+ if(df->BytesPerPixel == 2) {
+ /* the 16/32 interleaved format */
+ do {
+ /* skip opaque line */
+ ofs = 0;
+ do {
+ int run;
+ ofs += srcbuf[0];
+ run = srcbuf[1];
+ srcbuf += 2;
+ if(run) {
+ srcbuf += 2 * run;
+ ofs += run;
+ } else if(!ofs)
+ goto done;
+ } while(ofs < w);
+
+ /* skip padding */
+ srcbuf += (uintptr_t)srcbuf & 2;
+
+ /* skip translucent line */
+ ofs = 0;
+ do {
+ int run;
+ ofs += ((Uint16 *)srcbuf)[0];
+ run = ((Uint16 *)srcbuf)[1];
+ srcbuf += 4 * (run + 1);
+ ofs += run;
+ } while(ofs < w);
+ } while(--vskip);
+ } else {
+ /* the 32/32 interleaved format */
+ vskip <<= 1; /* opaque and translucent have same format */
+ do {
+ ofs = 0;
+ do {
+ int run;
+ ofs += ((Uint16 *)srcbuf)[0];
+ run = ((Uint16 *)srcbuf)[1];
+ srcbuf += 4;
+ if(run) {
+ srcbuf += 4 * run;
+ ofs += run;
+ } else if(!ofs)
+ goto done;
+ } while(ofs < w);
+ } while(--vskip);
+ }
+ }
+ }
+
+ /* if left or right edge clipping needed, call clip blit */
+ if(srcrect->x || srcrect->w != src->w) {
+ RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect);
+ } else {
+
+ /*
+ * non-clipped blitter. Ptype is the destination pixel type,
+ * Ctype the translucent count type, and do_blend the
+ * macro to blend one pixel.
+ */
+#define RLEALPHABLIT(Ptype, Ctype, do_blend) \
+ do { \
+ int linecount = srcrect->h; \
+ do { \
+ int ofs = 0; \
+ /* blit opaque pixels on one line */ \
+ do { \
+ unsigned run; \
+ ofs += ((Ctype *)srcbuf)[0]; \
+ run = ((Ctype *)srcbuf)[1]; \
+ srcbuf += 2 * sizeof(Ctype); \
+ if(run) { \
+ PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \
+ run, sizeof(Ptype)); \
+ srcbuf += run * sizeof(Ptype); \
+ ofs += run; \
+ } else if(!ofs) \
+ goto done; \
+ } while(ofs < w); \
+ /* skip padding if necessary */ \
+ if(sizeof(Ptype) == 2) \
+ srcbuf += (uintptr_t)srcbuf & 2; \
+ /* blit translucent pixels on the same line */ \
+ ofs = 0; \
+ do { \
+ unsigned run; \
+ ofs += ((Uint16 *)srcbuf)[0]; \
+ run = ((Uint16 *)srcbuf)[1]; \
+ srcbuf += 4; \
+ if(run) { \
+ Ptype *dst = (Ptype *)dstbuf + ofs; \
+ unsigned i; \
+ for(i = 0; i < run; i++) { \
+ Uint32 src = *(Uint32 *)srcbuf; \
+ do_blend(src, *dst); \
+ srcbuf += 4; \
+ dst++; \
+ } \
+ ofs += run; \
+ } \
+ } while(ofs < w); \
+ dstbuf += dst->pitch; \
+ } while(--linecount); \
+ } while(0)
+
+ switch(df->BytesPerPixel) {
+ case 2:
+ if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0
+ || df->Bmask == 0x07e0)
+ RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565);
+ else
+ RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555);
+ break;
+ case 4:
+ RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888);
+ break;
+ }
+ }
+
+ done:
+ /* Unlock the destination if necessary */
+ if ( SDL_MUSTLOCK(dst) ) {
+ SDL_UnlockSurface(dst);
+ }
+ return 0;
+}
+
+/*
+ * Auxiliary functions:
+ * The encoding functions take 32bpp rgb + a, and
+ * return the number of bytes copied to the destination.
+ * The decoding functions copy to 32bpp rgb + a, and
+ * return the number of bytes copied from the source.
+ * These are only used in the encoder and un-RLE code and are therefore not
+ * highly optimised.
+ */
+
+/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */
+static int copy_opaque_16(void *dst, Uint32 *src, int n,
+ SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint16 *d = dst;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b;
+ RGB_FROM_PIXEL(*src, sfmt, r, g, b);
+ PIXEL_FROM_RGB(*d, dfmt, r, g, b);
+ src++;
+ d++;
+ }
+ return n * 2;
+}
+
+/* decode opaque pixels from 16bpp to 32bpp rgb + a */
+static int uncopy_opaque_16(Uint32 *dst, void *src, int n,
+ RLEDestFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint16 *s = src;
+ unsigned alpha = dfmt->Amask ? 255 : 0;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b;
+ RGB_FROM_PIXEL(*s, sfmt, r, g, b);
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha);
+ s++;
+ dst++;
+ }
+ return n * 2;
+}
+
+
+
+/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */
+static int copy_transl_565(void *dst, Uint32 *src, int n,
+ SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint16 pix;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ PIXEL_FROM_RGB(pix, dfmt, r, g, b);
+ *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0);
+ src++;
+ d++;
+ }
+ return n * 4;
+}
+
+/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */
+static int copy_transl_555(void *dst, Uint32 *src, int n,
+ SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint16 pix;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ PIXEL_FROM_RGB(pix, dfmt, r, g, b);
+ *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);
+ src++;
+ d++;
+ }
+ return n * 4;
+}
+
+/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */
+static int uncopy_transl_16(Uint32 *dst, void *src, int n,
+ RLEDestFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint32 *s = src;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint32 pix = *s++;
+ a = (pix & 0x3e0) >> 2;
+ pix = (pix & ~0x3e0) | pix >> 16;
+ RGB_FROM_PIXEL(pix, sfmt, r, g, b);
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);
+ dst++;
+ }
+ return n * 4;
+}
+
+/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */
+static int copy_32(void *dst, Uint32 *src, int n,
+ SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint32 *d = dst;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint32 pixel;
+ RGBA_FROM_8888(*src, sfmt, r, g, b, a);
+ PIXEL_FROM_RGB(pixel, dfmt, r, g, b);
+ *d++ = pixel | a << 24;
+ src++;
+ }
+ return n * 4;
+}
+
+/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */
+static int uncopy_32(Uint32 *dst, void *src, int n,
+ RLEDestFormat *sfmt, SDL_PixelFormat *dfmt)
+{
+ int i;
+ Uint32 *s = src;
+ for(i = 0; i < n; i++) {
+ unsigned r, g, b, a;
+ Uint32 pixel = *s++;
+ RGB_FROM_PIXEL(pixel, sfmt, r, g, b);
+ a = pixel >> 24;
+ PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);
+ dst++;
+ }
+ return n * 4;
+}
+
+#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255)
+
+#define ISTRANSL(pixel, fmt) \
+ ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U)
+
+/* convert surface to be quickly alpha-blittable onto dest, if possible */
+static int RLEAlphaSurface(SDL_Surface *surface)
+{
+ SDL_Surface *dest;
+ SDL_PixelFormat *df;
+ int maxsize = 0;
+ int max_opaque_run;
+ int max_transl_run = 65535;
+ unsigned masksum;
+ Uint8 *rlebuf, *dst;
+ int (*copy_opaque)(void *, Uint32 *, int,
+ SDL_PixelFormat *, SDL_PixelFormat *);
+ int (*copy_transl)(void *, Uint32 *, int,
+ SDL_PixelFormat *, SDL_PixelFormat *);
+
+ dest = surface->map->dst;
+ if(!dest)
+ return -1;
+ df = dest->format;
+ if(surface->format->BitsPerPixel != 32)
+ return -1; /* only 32bpp source supported */
+
+ /* find out whether the destination is one we support,
+ and determine the max size of the encoded result */
+ masksum = df->Rmask | df->Gmask | df->Bmask;
+ switch(df->BytesPerPixel) {
+ case 2:
+ /* 16bpp: only support 565 and 555 formats */
+ switch(masksum) {
+ case 0xffff:
+ if(df->Gmask == 0x07e0
+ || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) {
+ copy_opaque = copy_opaque_16;
+ copy_transl = copy_transl_565;
+ } else
+ return -1;
+ break;
+ case 0x7fff:
+ if(df->Gmask == 0x03e0
+ || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) {
+ copy_opaque = copy_opaque_16;
+ copy_transl = copy_transl_555;
+ } else
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ max_opaque_run = 255; /* runs stored as bytes */
+
+ /* worst case is alternating opaque and translucent pixels,
+ with room for alignment padding between lines */
+ maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2;
+ break;
+ case 4:
+ if(masksum != 0x00ffffff)
+ return -1; /* requires unused high byte */
+ copy_opaque = copy_32;
+ copy_transl = copy_32;
+ max_opaque_run = 255; /* runs stored as short ints */
+
+ /* worst case is alternating opaque and translucent pixels */
+ maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4;
+ break;
+ default:
+ return -1; /* anything else unsupported right now */
+ }
+
+ maxsize += sizeof(RLEDestFormat);
+ rlebuf = (Uint8 *)SDL_malloc(maxsize);
+ if(!rlebuf) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ {
+ /* save the destination format so we can undo the encoding later */
+ RLEDestFormat *r = (RLEDestFormat *)rlebuf;
+ r->BytesPerPixel = df->BytesPerPixel;
+ r->Rloss = df->Rloss;
+ r->Gloss = df->Gloss;
+ r->Bloss = df->Bloss;
+ r->Rshift = df->Rshift;
+ r->Gshift = df->Gshift;
+ r->Bshift = df->Bshift;
+ r->Ashift = df->Ashift;
+ r->Rmask = df->Rmask;
+ r->Gmask = df->Gmask;
+ r->Bmask = df->Bmask;
+ r->Amask = df->Amask;
+ }
+ dst = rlebuf + sizeof(RLEDestFormat);
+
+ /* Do the actual encoding */
+ {
+ int x, y;
+ int h = surface->h, w = surface->w;
+ SDL_PixelFormat *sf = surface->format;
+ Uint32 *src = (Uint32 *)surface->pixels;
+ Uint8 *lastline = dst; /* end of last non-blank line */
+
+ /* opaque counts are 8 or 16 bits, depending on target depth */
+#define ADD_OPAQUE_COUNTS(n, m) \
+ if(df->BytesPerPixel == 4) { \
+ ((Uint16 *)dst)[0] = n; \
+ ((Uint16 *)dst)[1] = m; \
+ dst += 4; \
+ } else { \
+ dst[0] = n; \
+ dst[1] = m; \
+ dst += 2; \
+ }
+
+ /* translucent counts are always 16 bit */
+#define ADD_TRANSL_COUNTS(n, m) \
+ (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4)
+
+ for(y = 0; y < h; y++) {
+ int runstart, skipstart;
+ int blankline = 0;
+ /* First encode all opaque pixels of a scan line */
+ x = 0;
+ do {
+ int run, skip, len;
+ skipstart = x;
+ while(x < w && !ISOPAQUE(src[x], sf))
+ x++;
+ runstart = x;
+ while(x < w && ISOPAQUE(src[x], sf))
+ x++;
+ skip = runstart - skipstart;
+ if(skip == w)
+ blankline = 1;
+ run = x - runstart;
+ while(skip > max_opaque_run) {
+ ADD_OPAQUE_COUNTS(max_opaque_run, 0);
+ skip -= max_opaque_run;
+ }
+ len = MIN(run, max_opaque_run);
+ ADD_OPAQUE_COUNTS(skip, len);
+ dst += copy_opaque(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ while(run) {
+ len = MIN(run, max_opaque_run);
+ ADD_OPAQUE_COUNTS(0, len);
+ dst += copy_opaque(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ }
+ } while(x < w);
+
+ /* Make sure the next output address is 32-bit aligned */
+ dst += (uintptr_t)dst & 2;
+
+ /* Next, encode all translucent pixels of the same scan line */
+ x = 0;
+ do {
+ int run, skip, len;
+ skipstart = x;
+ while(x < w && !ISTRANSL(src[x], sf))
+ x++;
+ runstart = x;
+ while(x < w && ISTRANSL(src[x], sf))
+ x++;
+ skip = runstart - skipstart;
+ blankline &= (skip == w);
+ run = x - runstart;
+ while(skip > max_transl_run) {
+ ADD_TRANSL_COUNTS(max_transl_run, 0);
+ skip -= max_transl_run;
+ }
+ len = MIN(run, max_transl_run);
+ ADD_TRANSL_COUNTS(skip, len);
+ dst += copy_transl(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ while(run) {
+ len = MIN(run, max_transl_run);
+ ADD_TRANSL_COUNTS(0, len);
+ dst += copy_transl(dst, src + runstart, len, sf, df);
+ runstart += len;
+ run -= len;
+ }
+ if(!blankline)
+ lastline = dst;
+ } while(x < w);
+
+ src += surface->pitch >> 2;
+ }
+ dst = lastline; /* back up past trailing blank lines */
+ ADD_OPAQUE_COUNTS(0, 0);
+ }
+
+#undef ADD_OPAQUE_COUNTS
+#undef ADD_TRANSL_COUNTS
+
+ /* Now that we have it encoded, release the original pixels */
+ if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC
+ && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
+ SDL_free( surface->pixels );
+ surface->pixels = NULL;
+ }
+
+ /* realloc the buffer to release unused memory */
+ {
+ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
+ if(!p)
+ p = rlebuf;
+ surface->map->sw_data->aux_data = p;
+ }
+
+ return 0;
+}
+
+static Uint32 getpix_8(Uint8 *srcbuf)
+{
+ return *srcbuf;
+}
+
+static Uint32 getpix_16(Uint8 *srcbuf)
+{
+ return *(Uint16 *)srcbuf;
+}
+
+static Uint32 getpix_24(Uint8 *srcbuf)
+{
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16);
+#else
+ return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2];
+#endif
+}
+
+static Uint32 getpix_32(Uint8 *srcbuf)
+{
+ return *(Uint32 *)srcbuf;
+}
+
+typedef Uint32 (*getpix_func)(Uint8 *);
+
+static getpix_func getpixes[4] = {
+ getpix_8, getpix_16, getpix_24, getpix_32
+};
+
+static int RLEColorkeySurface(SDL_Surface *surface)
+{
+ Uint8 *rlebuf, *dst;
+ int maxn;
+ int y;
+ Uint8 *srcbuf, *lastline;
+ int maxsize = 0;
+ int bpp = surface->format->BytesPerPixel;
+ getpix_func getpix;
+ Uint32 ckey, rgbmask;
+ int w, h;
+
+ /* calculate the worst case size for the compressed surface */
+ switch(bpp) {
+ case 1:
+ /* worst case is alternating opaque and transparent pixels,
+ starting with an opaque pixel */
+ maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2;
+ break;
+ case 2:
+ case 3:
+ /* worst case is solid runs, at most 255 pixels wide */
+ maxsize = surface->h * (2 * (surface->w / 255 + 1)
+ + surface->w * bpp) + 2;
+ break;
+ case 4:
+ /* worst case is solid runs, at most 65535 pixels wide */
+ maxsize = surface->h * (4 * (surface->w / 65535 + 1)
+ + surface->w * 4) + 4;
+ break;
+ }
+
+ rlebuf = (Uint8 *)SDL_malloc(maxsize);
+ if ( rlebuf == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+
+ /* Set up the conversion */
+ srcbuf = (Uint8 *)surface->pixels;
+ maxn = bpp == 4 ? 65535 : 255;
+ dst = rlebuf;
+ rgbmask = ~surface->format->Amask;
+ ckey = surface->format->colorkey & rgbmask;
+ lastline = dst;
+ getpix = getpixes[bpp - 1];
+ w = surface->w;
+ h = surface->h;
+
+#define ADD_COUNTS(n, m) \
+ if(bpp == 4) { \
+ ((Uint16 *)dst)[0] = n; \
+ ((Uint16 *)dst)[1] = m; \
+ dst += 4; \
+ } else { \
+ dst[0] = n; \
+ dst[1] = m; \
+ dst += 2; \
+ }
+
+ for(y = 0; y < h; y++) {
+ int x = 0;
+ int blankline = 0;
+ do {
+ int run, skip, len;
+ int runstart;
+ int skipstart = x;
+
+ /* find run of transparent, then opaque pixels */
+ while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey)
+ x++;
+ runstart = x;
+ while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey)
+ x++;
+ skip = runstart - skipstart;
+ if(skip == w)
+ blankline = 1;
+ run = x - runstart;
+
+ /* encode segment */
+ while(skip > maxn) {
+ ADD_COUNTS(maxn, 0);
+ skip -= maxn;
+ }
+ len = MIN(run, maxn);
+ ADD_COUNTS(skip, len);
+ SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp);
+ dst += len * bpp;
+ run -= len;
+ runstart += len;
+ while(run) {
+ len = MIN(run, maxn);
+ ADD_COUNTS(0, len);
+ SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp);
+ dst += len * bpp;
+ runstart += len;
+ run -= len;
+ }
+ if(!blankline)
+ lastline = dst;
+ } while(x < w);
+
+ srcbuf += surface->pitch;
+ }
+ dst = lastline; /* back up bast trailing blank lines */
+ ADD_COUNTS(0, 0);
+
+#undef ADD_COUNTS
+
+ /* Now that we have it encoded, release the original pixels */
+ if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC
+ && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
+ SDL_free( surface->pixels );
+ surface->pixels = NULL;
+ }
+
+ /* realloc the buffer to release unused memory */
+ {
+ /* If realloc returns NULL, the original block is left intact */
+ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
+ if(!p)
+ p = rlebuf;
+ surface->map->sw_data->aux_data = p;
+ }
+
+ return(0);
+}
+
+int SDL_RLESurface(SDL_Surface *surface)
+{
+ int retcode;
+
+ /* Clear any previous RLE conversion */
+ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ SDL_UnRLESurface(surface, 1);
+ }
+
+ /* We don't support RLE encoding of bitmaps */
+ if ( surface->format->BitsPerPixel < 8 ) {
+ return(-1);
+ }
+
+ /* Lock the surface if it's in hardware */
+ if ( SDL_MUSTLOCK(surface) ) {
+ if ( SDL_LockSurface(surface) < 0 ) {
+ return(-1);
+ }
+ }
+
+ /* Encode */
+ if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
+ retcode = RLEColorkeySurface(surface);
+ } else {
+ if((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA
+ && surface->format->Amask != 0)
+ retcode = RLEAlphaSurface(surface);
+ else
+ retcode = -1; /* no RLE for per-surface alpha sans ckey */
+ }
+
+ /* Unlock the surface if it's in hardware */
+ if ( SDL_MUSTLOCK(surface) ) {
+ SDL_UnlockSurface(surface);
+ }
+
+ if(retcode < 0)
+ return -1;
+
+ /* The surface is now accelerated */
+ surface->flags |= SDL_RLEACCEL;
+
+ return(0);
+}
+
+/*
+ * Un-RLE a surface with pixel alpha
+ * This may not give back exactly the image before RLE-encoding; all
+ * completely transparent pixels will be lost, and colour and alpha depth
+ * may have been reduced (when encoding for 16bpp targets).
+ */
+static SDL_bool UnRLEAlpha(SDL_Surface *surface)
+{
+ Uint8 *srcbuf;
+ Uint32 *dst;
+ SDL_PixelFormat *sf = surface->format;
+ RLEDestFormat *df = surface->map->sw_data->aux_data;
+ int (*uncopy_opaque)(Uint32 *, void *, int,
+ RLEDestFormat *, SDL_PixelFormat *);
+ int (*uncopy_transl)(Uint32 *, void *, int,
+ RLEDestFormat *, SDL_PixelFormat *);
+ int w = surface->w;
+ int bpp = df->BytesPerPixel;
+
+ if(bpp == 2) {
+ uncopy_opaque = uncopy_opaque_16;
+ uncopy_transl = uncopy_transl_16;
+ } else {
+ uncopy_opaque = uncopy_transl = uncopy_32;
+ }
+
+ surface->pixels = SDL_malloc(surface->h * surface->pitch);
+ if ( !surface->pixels ) {
+ return(SDL_FALSE);
+ }
+ /* fill background with transparent pixels */
+ SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
+
+ dst = surface->pixels;
+ srcbuf = (Uint8 *)(df + 1);
+ for(;;) {
+ /* copy opaque pixels */
+ int ofs = 0;
+ do {
+ unsigned run;
+ if(bpp == 2) {
+ ofs += srcbuf[0];
+ run = srcbuf[1];
+ srcbuf += 2;
+ } else {
+ ofs += ((Uint16 *)srcbuf)[0];
+ run = ((Uint16 *)srcbuf)[1];
+ srcbuf += 4;
+ }
+ if(run) {
+ srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf);
+ ofs += run;
+ } else if(!ofs)
+ return(SDL_TRUE);
+ } while(ofs < w);
+
+ /* skip padding if needed */
+ if(bpp == 2)
+ srcbuf += (uintptr_t)srcbuf & 2;
+
+ /* copy translucent pixels */
+ ofs = 0;
+ do {
+ unsigned run;
+ ofs += ((Uint16 *)srcbuf)[0];
+ run = ((Uint16 *)srcbuf)[1];
+ srcbuf += 4;
+ if(run) {
+ srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf);
+ ofs += run;
+ }
+ } while(ofs < w);
+ dst += surface->pitch >> 2;
+ }
+ /* Make the compiler happy */
+ return(SDL_TRUE);
+}
+
+void SDL_UnRLESurface(SDL_Surface *surface, int recode)
+{
+ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ surface->flags &= ~SDL_RLEACCEL;
+
+ if(recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC
+ && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
+ if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
+ SDL_Rect full;
+ unsigned alpha_flag;
+
+ /* re-create the original surface */
+ surface->pixels = SDL_malloc(surface->h * surface->pitch);
+ if ( !surface->pixels ) {
+ /* Oh crap... */
+ surface->flags |= SDL_RLEACCEL;
+ return;
+ }
+
+ /* fill it with the background colour */
+ SDL_FillRect(surface, NULL, surface->format->colorkey);
+
+ /* now render the encoded surface */
+ full.x = full.y = 0;
+ full.w = surface->w;
+ full.h = surface->h;
+ alpha_flag = surface->flags & SDL_SRCALPHA;
+ surface->flags &= ~SDL_SRCALPHA; /* opaque blit */
+ SDL_RLEBlit(surface, &full, surface, &full);
+ surface->flags |= alpha_flag;
+ } else {
+ if ( !UnRLEAlpha(surface) ) {
+ /* Oh crap... */
+ surface->flags |= SDL_RLEACCEL;
+ return;
+ }
+ }
+ }
+
+ if ( surface->map && surface->map->sw_data->aux_data ) {
+ SDL_free(surface->map->sw_data->aux_data);
+ surface->map->sw_data->aux_data = NULL;
+ }
+ }
+}
+
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_RLEaccel_c.h b/distrib/sdl-1.2.15/src/video/SDL_RLEaccel_c.h
new file mode 100644
index 0000000..daf0c53
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_RLEaccel_c.h
@@ -0,0 +1,31 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Useful functions and variables from SDL_RLEaccel.c */
+
+extern int SDL_RLESurface(SDL_Surface *surface);
+extern int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+extern int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+extern void SDL_UnRLESurface(SDL_Surface *surface, int recode);
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit.c b/distrib/sdl-1.2.15/src/video/SDL_blit.c
new file mode 100644
index 0000000..e3f194a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit.c
@@ -0,0 +1,360 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_RLEaccel_c.h"
+#include "SDL_pixels_c.h"
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES
+#define MMX_ASMBLIT
+#if (__GNUC__ > 2) /* SSE instructions aren't in GCC 2. */
+#define SSE_ASMBLIT
+#endif
+#endif
+
+#if defined(MMX_ASMBLIT)
+#include "SDL_cpuinfo.h"
+#include "mmx.h"
+#endif
+
+/* The general purpose software blit routine */
+static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int okay;
+ int src_locked;
+ int dst_locked;
+
+ /* Everything is okay at the beginning... */
+ okay = 1;
+
+ /* Lock the destination if it's in hardware */
+ dst_locked = 0;
+ if ( SDL_MUSTLOCK(dst) ) {
+ if ( SDL_LockSurface(dst) < 0 ) {
+ okay = 0;
+ } else {
+ dst_locked = 1;
+ }
+ }
+ /* Lock the source if it's in hardware */
+ src_locked = 0;
+ if ( SDL_MUSTLOCK(src) ) {
+ if ( SDL_LockSurface(src) < 0 ) {
+ okay = 0;
+ } else {
+ src_locked = 1;
+ }
+ }
+
+ /* Set up source and destination buffer pointers, and BLIT! */
+ if ( okay && srcrect->w && srcrect->h ) {
+ SDL_BlitInfo info;
+ SDL_loblit RunBlit;
+
+ /* Set up the blit information */
+ info.s_pixels = (Uint8 *)src->pixels +
+ (Uint16)srcrect->y*src->pitch +
+ (Uint16)srcrect->x*src->format->BytesPerPixel;
+ info.s_width = srcrect->w;
+ info.s_height = srcrect->h;
+ info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel;
+ info.d_pixels = (Uint8 *)dst->pixels +
+ (Uint16)dstrect->y*dst->pitch +
+ (Uint16)dstrect->x*dst->format->BytesPerPixel;
+ info.d_width = dstrect->w;
+ info.d_height = dstrect->h;
+ info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel;
+ info.aux_data = src->map->sw_data->aux_data;
+ info.src = src->format;
+ info.table = src->map->table;
+ info.dst = dst->format;
+ RunBlit = src->map->sw_data->blit;
+
+ /* Run the actual software blit */
+ RunBlit(&info);
+ }
+
+ /* We need to unlock the surfaces if they're locked */
+ if ( dst_locked ) {
+ SDL_UnlockSurface(dst);
+ }
+ if ( src_locked ) {
+ SDL_UnlockSurface(src);
+ }
+ /* Blit is done! */
+ return(okay ? 0 : -1);
+}
+
+#ifdef MMX_ASMBLIT
+static __inline__ void SDL_memcpyMMX(Uint8 *to, const Uint8 *from, int len)
+{
+ int i;
+
+ for(i=0; i<len/8; i++) {
+ __asm__ __volatile__ (
+ " movq (%0), %%mm0\n"
+ " movq %%mm0, (%1)\n"
+ : : "r" (from), "r" (to) : "memory");
+ from+=8;
+ to+=8;
+ }
+ if (len&7)
+ SDL_memcpy(to, from, len&7);
+}
+
+#ifdef SSE_ASMBLIT
+static __inline__ void SDL_memcpySSE(Uint8 *to, const Uint8 *from, int len)
+{
+ int i;
+
+ __asm__ __volatile__ (
+ " prefetchnta (%0)\n"
+ " prefetchnta 64(%0)\n"
+ " prefetchnta 128(%0)\n"
+ " prefetchnta 192(%0)\n"
+ : : "r" (from) );
+
+ for(i=0; i<len/8; i++) {
+ __asm__ __volatile__ (
+ " prefetchnta 256(%0)\n"
+ " movq (%0), %%mm0\n"
+ " movntq %%mm0, (%1)\n"
+ : : "r" (from), "r" (to) : "memory");
+ from+=8;
+ to+=8;
+ }
+ if (len&7)
+ SDL_memcpy(to, from, len&7);
+}
+#endif
+#endif
+
+static void SDL_BlitCopy(SDL_BlitInfo *info)
+{
+ Uint8 *src, *dst;
+ int w, h;
+ int srcskip, dstskip;
+
+ w = info->d_width*info->dst->BytesPerPixel;
+ h = info->d_height;
+ src = info->s_pixels;
+ dst = info->d_pixels;
+ srcskip = w+info->s_skip;
+ dstskip = w+info->d_skip;
+
+#ifdef SSE_ASMBLIT
+ if(SDL_HasSSE())
+ {
+ while ( h-- ) {
+ SDL_memcpySSE(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ __asm__ __volatile__ (
+ " emms\n"
+ ::);
+ }
+ else
+#endif
+#ifdef MMX_ASMBLIT
+ if(SDL_HasMMX())
+ {
+ while ( h-- ) {
+ SDL_memcpyMMX(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ __asm__ __volatile__ (
+ " emms\n"
+ ::);
+ }
+ else
+#endif
+ while ( h-- ) {
+ SDL_memcpy(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void SDL_BlitCopyOverlap(SDL_BlitInfo *info)
+{
+ Uint8 *src, *dst;
+ int w, h;
+ int srcskip, dstskip;
+
+ w = info->d_width*info->dst->BytesPerPixel;
+ h = info->d_height;
+ src = info->s_pixels;
+ dst = info->d_pixels;
+ srcskip = w+info->s_skip;
+ dstskip = w+info->d_skip;
+ if ( dst < src ) {
+ while ( h-- ) {
+ SDL_memmove(dst, src, w);
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ src += ((h-1) * srcskip);
+ dst += ((h-1) * dstskip);
+ while ( h-- ) {
+ SDL_revcpy(dst, src, w);
+ src -= srcskip;
+ dst -= dstskip;
+ }
+ }
+}
+
+/* Figure out which of many blit routines to set up on a surface */
+int SDL_CalculateBlit(SDL_Surface *surface)
+{
+ int blit_index;
+
+ /* Clean everything out to start */
+ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ SDL_UnRLESurface(surface, 1);
+ }
+ surface->map->sw_blit = NULL;
+
+ /* Figure out if an accelerated hardware blit is possible */
+ surface->flags &= ~SDL_HWACCEL;
+ if ( surface->map->identity ) {
+ int hw_blit_ok;
+
+ if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ /* We only support accelerated blitting to hardware */
+ if ( surface->map->dst->flags & SDL_HWSURFACE ) {
+ hw_blit_ok = current_video->info.blit_hw;
+ } else {
+ hw_blit_ok = 0;
+ }
+ if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) {
+ hw_blit_ok = current_video->info.blit_hw_CC;
+ }
+ if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) {
+ hw_blit_ok = current_video->info.blit_hw_A;
+ }
+ } else {
+ /* We only support accelerated blitting to hardware */
+ if ( surface->map->dst->flags & SDL_HWSURFACE ) {
+ hw_blit_ok = current_video->info.blit_sw;
+ } else {
+ hw_blit_ok = 0;
+ }
+ if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) {
+ hw_blit_ok = current_video->info.blit_sw_CC;
+ }
+ if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) {
+ hw_blit_ok = current_video->info.blit_sw_A;
+ }
+ }
+ if ( hw_blit_ok ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ video->CheckHWBlit(this, surface, surface->map->dst);
+ }
+ }
+
+ /* if an alpha pixel format is specified, we can accelerate alpha blits */
+ if (((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE )&&(current_video->displayformatalphapixel))
+ {
+ if ( (surface->flags & SDL_SRCALPHA) )
+ if ( current_video->info.blit_hw_A ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ video->CheckHWBlit(this, surface, surface->map->dst);
+ }
+ }
+
+ /* Get the blit function index, based on surface mode */
+ /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */
+ blit_index = 0;
+ blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0;
+ if ( surface->flags & SDL_SRCALPHA
+ && (surface->format->alpha != SDL_ALPHA_OPAQUE
+ || surface->format->Amask) ) {
+ blit_index |= 2;
+ }
+
+ /* Check for special "identity" case -- copy blit */
+ if ( surface->map->identity && blit_index == 0 ) {
+ surface->map->sw_data->blit = SDL_BlitCopy;
+
+ /* Handle overlapping blits on the same surface */
+ if ( surface == surface->map->dst ) {
+ surface->map->sw_data->blit = SDL_BlitCopyOverlap;
+ }
+ } else {
+ if ( surface->format->BitsPerPixel < 8 ) {
+ surface->map->sw_data->blit =
+ SDL_CalculateBlit0(surface, blit_index);
+ } else {
+ switch ( surface->format->BytesPerPixel ) {
+ case 1:
+ surface->map->sw_data->blit =
+ SDL_CalculateBlit1(surface, blit_index);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ surface->map->sw_data->blit =
+ SDL_CalculateBlitN(surface, blit_index);
+ break;
+ default:
+ surface->map->sw_data->blit = NULL;
+ break;
+ }
+ }
+ }
+ /* Make sure we have a blit function */
+ if ( surface->map->sw_data->blit == NULL ) {
+ SDL_InvalidateMap(surface->map);
+ SDL_SetError("Blit combination not supported");
+ return(-1);
+ }
+
+ /* Choose software blitting function */
+ if(surface->flags & SDL_RLEACCELOK
+ && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) {
+
+ if(surface->map->identity
+ && (blit_index == 1
+ || (blit_index == 3 && !surface->format->Amask))) {
+ if ( SDL_RLESurface(surface) == 0 )
+ surface->map->sw_blit = SDL_RLEBlit;
+ } else if(blit_index == 2 && surface->format->Amask) {
+ if ( SDL_RLESurface(surface) == 0 )
+ surface->map->sw_blit = SDL_RLEAlphaBlit;
+ }
+ }
+
+ if ( surface->map->sw_blit == NULL ) {
+ surface->map->sw_blit = SDL_SoftBlit;
+ }
+ return(0);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit.h b/distrib/sdl-1.2.15/src/video/SDL_blit.h
new file mode 100644
index 0000000..d64c1e5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit.h
@@ -0,0 +1,528 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_blit_h
+#define _SDL_blit_h
+
+#include "SDL_endian.h"
+
+/* The structure passed to the low level blit functions */
+typedef struct {
+ Uint8 *s_pixels;
+ int s_width;
+ int s_height;
+ int s_skip;
+ Uint8 *d_pixels;
+ int d_width;
+ int d_height;
+ int d_skip;
+ void *aux_data;
+ SDL_PixelFormat *src;
+ Uint8 *table;
+ SDL_PixelFormat *dst;
+} SDL_BlitInfo;
+
+/* The type definition for the low level blit functions */
+typedef void (*SDL_loblit)(SDL_BlitInfo *info);
+
+/* This is the private info structure for software accelerated blits */
+struct private_swaccel {
+ SDL_loblit blit;
+ void *aux_data;
+};
+
+/* Blit mapping definition */
+typedef struct SDL_BlitMap {
+ SDL_Surface *dst;
+ int identity;
+ Uint8 *table;
+ SDL_blit hw_blit;
+ SDL_blit sw_blit;
+ struct private_hwaccel *hw_data;
+ struct private_swaccel *sw_data;
+
+ /* the version count matches the destination; mismatch indicates
+ an invalid mapping */
+ unsigned int format_version;
+} SDL_BlitMap;
+
+
+/* Functions found in SDL_blit.c */
+extern int SDL_CalculateBlit(SDL_Surface *surface);
+
+/* Functions found in SDL_blit_{0,1,N,A}.c */
+extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex);
+extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex);
+extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex);
+extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex);
+
+/*
+ * Useful macros for blitting routines
+ */
+
+#define FORMAT_EQUAL(A, B) \
+ ((A)->BitsPerPixel == (B)->BitsPerPixel \
+ && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
+
+/* Load pixel of the specified format from a buffer and get its R-G-B values */
+/* FIXME: rescale values to 0..255 here? */
+#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \
+{ \
+ r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); \
+ g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); \
+ b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); \
+}
+#define RGB_FROM_RGB565(Pixel, r, g, b) \
+{ \
+ r = (((Pixel&0xF800)>>11)<<3); \
+ g = (((Pixel&0x07E0)>>5)<<2); \
+ b = ((Pixel&0x001F)<<3); \
+}
+#define RGB_FROM_RGB555(Pixel, r, g, b) \
+{ \
+ r = (((Pixel&0x7C00)>>10)<<3); \
+ g = (((Pixel&0x03E0)>>5)<<3); \
+ b = ((Pixel&0x001F)<<3); \
+}
+#define RGB_FROM_RGB888(Pixel, r, g, b) \
+{ \
+ r = ((Pixel&0xFF0000)>>16); \
+ g = ((Pixel&0xFF00)>>8); \
+ b = (Pixel&0xFF); \
+}
+#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \
+do { \
+ switch (bpp) { \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ break; \
+ \
+ case 3: { \
+ Uint8 *B = (Uint8 *)(buf); \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
+ } else { \
+ Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
+ } \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ break; \
+ \
+ default: \
+ Pixel = 0; /* appease gcc */ \
+ break; \
+ } \
+} while(0)
+
+#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \
+do { \
+ switch (bpp) { \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ break; \
+ \
+ case 3: { \
+ Uint8 *B = (Uint8 *)buf; \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
+ } else { \
+ Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
+ } \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ break; \
+ \
+ default: \
+ Pixel = 0; /* prevent gcc from complaining */ \
+ break; \
+ } \
+ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
+} while(0)
+
+/* Assemble R-G-B values into a specified pixel format and store them */
+#ifdef __NDS__ /* FIXME */
+#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift) | (1<<15); \
+}
+#else
+#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift); \
+}
+#endif /* __NDS__ FIXME */
+#define RGB565_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \
+}
+#define RGB555_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \
+}
+#define RGB888_FROM_RGB(Pixel, r, g, b) \
+{ \
+ Pixel = (r<<16)|(g<<8)|b; \
+}
+#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \
+{ \
+ switch (bpp) { \
+ case 2: { \
+ Uint16 Pixel; \
+ \
+ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
+ *((Uint16 *)(buf)) = Pixel; \
+ } \
+ break; \
+ \
+ case 3: { \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ *((buf)+fmt->Rshift/8) = r; \
+ *((buf)+fmt->Gshift/8) = g; \
+ *((buf)+fmt->Bshift/8) = b; \
+ } else { \
+ *((buf)+2-fmt->Rshift/8) = r; \
+ *((buf)+2-fmt->Gshift/8) = g; \
+ *((buf)+2-fmt->Bshift/8) = b; \
+ } \
+ } \
+ break; \
+ \
+ case 4: { \
+ Uint32 Pixel; \
+ \
+ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
+ *((Uint32 *)(buf)) = Pixel; \
+ } \
+ break; \
+ } \
+}
+#define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask) \
+{ \
+ switch (bpp) { \
+ case 2: { \
+ Uint16 *bufp; \
+ Uint16 Pixel; \
+ \
+ bufp = (Uint16 *)buf; \
+ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
+ *bufp = Pixel | (*bufp & Amask); \
+ } \
+ break; \
+ \
+ case 3: { \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ *((buf)+fmt->Rshift/8) = r; \
+ *((buf)+fmt->Gshift/8) = g; \
+ *((buf)+fmt->Bshift/8) = b; \
+ } else { \
+ *((buf)+2-fmt->Rshift/8) = r; \
+ *((buf)+2-fmt->Gshift/8) = g; \
+ *((buf)+2-fmt->Bshift/8) = b; \
+ } \
+ } \
+ break; \
+ \
+ case 4: { \
+ Uint32 *bufp; \
+ Uint32 Pixel; \
+ \
+ bufp = (Uint32 *)buf; \
+ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
+ *bufp = Pixel | (*bufp & Amask); \
+ } \
+ break; \
+ } \
+}
+
+/* FIXME: Should we rescale alpha into 0..255 here? */
+#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \
+{ \
+ r = ((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; \
+ g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; \
+ b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; \
+ a = ((Pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss; \
+}
+#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \
+{ \
+ r = (Pixel&fmt->Rmask)>>fmt->Rshift; \
+ g = (Pixel&fmt->Gmask)>>fmt->Gshift; \
+ b = (Pixel&fmt->Bmask)>>fmt->Bshift; \
+ a = (Pixel&fmt->Amask)>>fmt->Ashift; \
+}
+#define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \
+{ \
+ r = (Pixel>>24); \
+ g = ((Pixel>>16)&0xFF); \
+ b = ((Pixel>>8)&0xFF); \
+ a = (Pixel&0xFF); \
+}
+#define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \
+{ \
+ r = ((Pixel>>16)&0xFF); \
+ g = ((Pixel>>8)&0xFF); \
+ b = (Pixel&0xFF); \
+ a = (Pixel>>24); \
+}
+#define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \
+{ \
+ r = (Pixel&0xFF); \
+ g = ((Pixel>>8)&0xFF); \
+ b = ((Pixel>>16)&0xFF); \
+ a = (Pixel>>24); \
+}
+#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \
+do { \
+ switch (bpp) { \
+ case 2: \
+ Pixel = *((Uint16 *)(buf)); \
+ break; \
+ \
+ case 3: {/* FIXME: broken code (no alpha) */ \
+ Uint8 *b = (Uint8 *)buf; \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ Pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
+ } else { \
+ Pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
+ } \
+ } \
+ break; \
+ \
+ case 4: \
+ Pixel = *((Uint32 *)(buf)); \
+ break; \
+ \
+ default: \
+ Pixel = 0; /* stop gcc complaints */ \
+ break; \
+ } \
+ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
+ Pixel &= ~fmt->Amask; \
+} while(0)
+
+/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
+#ifdef __NDS__ /* FIXME */
+#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ ((a>>fmt->Aloss)<<fmt->Ashift) | (1<<15); \
+}
+#else
+#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \
+{ \
+ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
+ ((g>>fmt->Gloss)<<fmt->Gshift)| \
+ ((b>>fmt->Bloss)<<fmt->Bshift)| \
+ ((a>>fmt->Aloss)<<fmt->Ashift); \
+}
+#endif /* __NDS__ FIXME */
+#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
+{ \
+ switch (bpp) { \
+ case 2: { \
+ Uint16 Pixel; \
+ \
+ PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
+ *((Uint16 *)(buf)) = Pixel; \
+ } \
+ break; \
+ \
+ case 3: { /* FIXME: broken code (no alpha) */ \
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
+ *((buf)+fmt->Rshift/8) = r; \
+ *((buf)+fmt->Gshift/8) = g; \
+ *((buf)+fmt->Bshift/8) = b; \
+ } else { \
+ *((buf)+2-fmt->Rshift/8) = r; \
+ *((buf)+2-fmt->Gshift/8) = g; \
+ *((buf)+2-fmt->Bshift/8) = b; \
+ } \
+ } \
+ break; \
+ \
+ case 4: { \
+ Uint32 Pixel; \
+ \
+ PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
+ *((Uint32 *)(buf)) = Pixel; \
+ } \
+ break; \
+ } \
+}
+
+/* Blend the RGB values of two Pixels based on a source alpha value */
+#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \
+do { \
+ dR = (((sR-dR)*(A)+255)>>8)+dR; \
+ dG = (((sG-dG)*(A)+255)>>8)+dG; \
+ dB = (((sB-dB)*(A)+255)>>8)+dB; \
+} while(0)
+
+
+/* This is a very useful loop for optimizing blitters */
+#if defined(_MSC_VER) && (_MSC_VER == 1300)
+/* There's a bug in the Visual C++ 7 optimizer when compiling this code */
+#else
+#define USE_DUFFS_LOOP
+#endif
+#ifdef USE_DUFFS_LOOP
+
+/* 8-times unrolled loop */
+#define DUFFS_LOOP8(pixel_copy_increment, width) \
+{ int n = (width+7)/8; \
+ switch (width & 7) { \
+ case 0: do { pixel_copy_increment; \
+ case 7: pixel_copy_increment; \
+ case 6: pixel_copy_increment; \
+ case 5: pixel_copy_increment; \
+ case 4: pixel_copy_increment; \
+ case 3: pixel_copy_increment; \
+ case 2: pixel_copy_increment; \
+ case 1: pixel_copy_increment; \
+ } while ( --n > 0 ); \
+ } \
+}
+
+/* 4-times unrolled loop */
+#define DUFFS_LOOP4(pixel_copy_increment, width) \
+{ int n = (width+3)/4; \
+ switch (width & 3) { \
+ case 0: do { pixel_copy_increment; \
+ case 3: pixel_copy_increment; \
+ case 2: pixel_copy_increment; \
+ case 1: pixel_copy_increment; \
+ } while ( --n > 0 ); \
+ } \
+}
+
+/* 2 - times unrolled loop */
+#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \
+ double_pixel_copy_increment, width) \
+{ int n, w = width; \
+ if( w & 1 ) { \
+ pixel_copy_increment; \
+ w--; \
+ } \
+ if ( w > 0 ) { \
+ n = ( w + 2) / 4; \
+ switch( w & 2 ) { \
+ case 0: do { double_pixel_copy_increment; \
+ case 2: double_pixel_copy_increment; \
+ } while ( --n > 0 ); \
+ } \
+ } \
+}
+
+/* 2 - times unrolled loop 4 pixels */
+#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \
+ double_pixel_copy_increment, \
+ quatro_pixel_copy_increment, width) \
+{ int n, w = width; \
+ if(w & 1) { \
+ pixel_copy_increment; \
+ w--; \
+ } \
+ if(w & 2) { \
+ double_pixel_copy_increment; \
+ w -= 2; \
+ } \
+ if ( w > 0 ) { \
+ n = ( w + 7 ) / 8; \
+ switch( w & 4 ) { \
+ case 0: do { quatro_pixel_copy_increment; \
+ case 4: quatro_pixel_copy_increment; \
+ } while ( --n > 0 ); \
+ } \
+ } \
+}
+
+/* Use the 8-times version of the loop by default */
+#define DUFFS_LOOP(pixel_copy_increment, width) \
+ DUFFS_LOOP8(pixel_copy_increment, width)
+
+#else
+
+/* Don't use Duff's device to unroll loops */
+#define DUFFS_LOOP_DOUBLE2(pixel_copy_increment, \
+ double_pixel_copy_increment, width) \
+{ int n = width; \
+ if( n & 1 ) { \
+ pixel_copy_increment; \
+ n--; \
+ } \
+ n=n>>1; \
+ for(; n > 0; --n) { \
+ double_pixel_copy_increment; \
+ } \
+}
+
+/* Don't use Duff's device to unroll loops */
+#define DUFFS_LOOP_QUATRO2(pixel_copy_increment, \
+ double_pixel_copy_increment, \
+ quatro_pixel_copy_increment, width) \
+{ int n = width; \
+ if(n & 1) { \
+ pixel_copy_increment; \
+ n--; \
+ } \
+ if(n & 2) { \
+ double_pixel_copy_increment; \
+ n -= 2; \
+ } \
+ n=n>>2; \
+ for(; n > 0; --n) { \
+ quatro_pixel_copy_increment; \
+ } \
+}
+
+/* Don't use Duff's device to unroll loops */
+#define DUFFS_LOOP(pixel_copy_increment, width) \
+{ int n; \
+ for ( n=width; n > 0; --n ) { \
+ pixel_copy_increment; \
+ } \
+}
+#define DUFFS_LOOP8(pixel_copy_increment, width) \
+ DUFFS_LOOP(pixel_copy_increment, width)
+#define DUFFS_LOOP4(pixel_copy_increment, width) \
+ DUFFS_LOOP(pixel_copy_increment, width)
+
+#endif /* USE_DUFFS_LOOP */
+
+/* Prevent Visual C++ 6.0 from printing out stupid warnings */
+#if defined(_MSC_VER) && (_MSC_VER >= 600)
+#pragma warning(disable: 4550)
+#endif
+
+#endif /* _SDL_blit_h */
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit_0.c b/distrib/sdl-1.2.15/src/video/SDL_blit_0.c
new file mode 100644
index 0000000..c1bc0eb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit_0.c
@@ -0,0 +1,471 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* Functions to blit from bitmaps to other surfaces */
+
+static void BlitBto1(SDL_BlitInfo *info)
+{
+ int c;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+ srcskip += width-(width+7)/8;
+
+ if ( map ) {
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ *dst = map[bit];
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ *dst = bit;
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+static void BlitBto2(SDL_BlitInfo *info)
+{
+ int c;
+ int width, height;
+ Uint8 *src;
+ Uint16 *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = (Uint16 *)info->d_pixels;
+ dstskip = info->d_skip/2;
+ map = (Uint16 *)info->table;
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ *dst = map[bit];
+ }
+ byte <<= 1;
+ dst++;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+static void BlitBto3(SDL_BlitInfo *info)
+{
+ int c, o;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ o = bit * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ }
+ byte <<= 1;
+ dst += 3;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+static void BlitBto4(SDL_BlitInfo *info)
+{
+ int width, height;
+ Uint8 *src;
+ Uint32 *map, *dst;
+ int srcskip, dstskip;
+ int c;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = (Uint32 *)info->d_pixels;
+ dstskip = info->d_skip/4;
+ map = (Uint32 *)info->table;
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ *dst = map[bit];
+ }
+ byte <<= 1;
+ dst++;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitBto1Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint8 *dst = info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width-(width+7)/8;
+
+ if ( palmap ) {
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ *dst = palmap[bit];
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ *dst = bit;
+ }
+ dst++;
+ byte <<= 1;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void BlitBto2Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width-(width+7)/8;
+ dstskip /= 2;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ *dstp=((Uint16 *)palmap)[bit];
+ }
+ byte <<= 1;
+ dstp++;
+ }
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void BlitBto3Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint8 *dst = info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ SDL_memcpy(dst, &palmap[bit*4], 3);
+ }
+ byte <<= 1;
+ dst += 3;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitBto4Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ Uint8 *palmap = info->table;
+ int c;
+
+ /* Set up some basic variables */
+ srcskip += width-(width+7)/8;
+ dstskip /= 4;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ *dstp=((Uint32 *)palmap)[bit];
+ }
+ byte <<= 1;
+ dstp++;
+ }
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void BlitBtoNAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint8 *dst = info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ const SDL_Color *srcpal = info->src->palette->colors;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int dstbpp;
+ int c;
+ const int A = info->src->alpha;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( 1 ) {
+ Uint32 pixel;
+ unsigned sR, sG, sB;
+ unsigned dR, dG, dB;
+ sR = srcpal[bit].r;
+ sG = srcpal[bit].g;
+ sB = srcpal[bit].b;
+ DISEMBLE_RGB(dst, dstbpp, dstfmt,
+ pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+ }
+ byte <<= 1;
+ dst += dstbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitBtoNAlphaKey(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ Uint8 *dst = info->d_pixels;
+ int srcskip = info->s_skip;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ const SDL_Color *srcpal = srcfmt->palette->colors;
+ int dstbpp;
+ int c;
+ const int A = srcfmt->alpha;
+ Uint32 ckey = srcfmt->colorkey;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+ srcskip += width-(width+7)/8;
+
+ while ( height-- ) {
+ Uint8 byte = 0, bit;
+ for ( c=0; c<width; ++c ) {
+ if ( (c&7) == 0 ) {
+ byte = *src++;
+ }
+ bit = (byte&0x80)>>7;
+ if ( bit != ckey ) {
+ int sR, sG, sB;
+ int dR, dG, dB;
+ Uint32 pixel;
+ sR = srcpal[bit].r;
+ sG = srcpal[bit].g;
+ sB = srcpal[bit].b;
+ DISEMBLE_RGB(dst, dstbpp, dstfmt,
+ pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+ }
+ byte <<= 1;
+ dst += dstbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static SDL_loblit bitmap_blit[] = {
+ NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4
+};
+
+static SDL_loblit colorkey_blit[] = {
+ NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
+};
+
+SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index)
+{
+ int which;
+
+ if ( surface->format->BitsPerPixel != 1 ) {
+ /* We don't support sub 8-bit packed pixel modes */
+ return NULL;
+ }
+ if ( surface->map->dst->format->BitsPerPixel < 8 ) {
+ which = 0;
+ } else {
+ which = surface->map->dst->format->BytesPerPixel;
+ }
+ switch(blit_index) {
+ case 0: /* copy */
+ return bitmap_blit[which];
+
+ case 1: /* colorkey */
+ return colorkey_blit[which];
+
+ case 2: /* alpha */
+ return which >= 2 ? BlitBtoNAlpha : NULL;
+
+ case 4: /* alpha + colorkey */
+ return which >= 2 ? BlitBtoNAlphaKey : NULL;
+ }
+ return NULL;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit_1.c b/distrib/sdl-1.2.15/src/video/SDL_blit_1.c
new file mode 100644
index 0000000..7f95f5b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit_1.c
@@ -0,0 +1,523 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+#include "SDL_sysvideo.h"
+#include "SDL_endian.h"
+
+/* Functions to blit from 8-bit surfaces to other surfaces */
+
+static void Blit1to1(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ {
+ *dst = map[*src];
+ }
+ dst++;
+ src++;
+ , width);
+#else
+ for ( c=width; c; --c ) {
+ *dst = map[*src];
+ dst++;
+ src++;
+ }
+#endif
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+/* This is now endian dependent */
+#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
+#define HI 1
+#define LO 0
+#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
+#define HI 0
+#define LO 1
+#endif
+static void Blit1to2(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src, *dst;
+ Uint16 *map;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = (Uint16 *)info->table;
+
+#ifdef USE_DUFFS_LOOP
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ( (long)dst & 0x03 ) {
+ /* Don't do anything if width is 0 */
+ if ( width == 0 ) {
+ return;
+ }
+ --width;
+
+ while ( height-- ) {
+ /* Perform copy alignment */
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ case 2:
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ break;
+ case 1:
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ case 2:
+ *(Uint32 *)dst =
+ (map[src[HI]]<<16)|(map[src[LO]]);
+ src += 2;
+ dst += 4;
+ break;
+ case 1:
+ *(Uint16 *)dst = map[*src++];
+ dst += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+static void Blit1to3(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int o;
+ int width, height;
+ Uint8 *src, *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ {
+ o = *src * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ }
+ src++;
+ dst += 3;
+ , width);
+#else
+ for ( c=width; c; --c ) {
+ o = *src * 4;
+ dst[0] = map[o++];
+ dst[1] = map[o++];
+ dst[2] = map[o++];
+ src++;
+ dst += 3;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+static void Blit1to4(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ Uint32 *map, *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = (Uint32 *)info->d_pixels;
+ dstskip = info->d_skip/4;
+ map = (Uint32 *)info->table;
+
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ *dst++ = map[*src++];
+ , width);
+#else
+ for ( c=width/4; c; --c ) {
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ *dst++ = map[*src++];
+ }
+ switch ( width & 3 ) {
+ case 3:
+ *dst++ = map[*src++];
+ case 2:
+ *dst++ = map[*src++];
+ case 1:
+ *dst++ = map[*src++];
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void Blit1to1Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint8 *palmap = info->table;
+ Uint32 ckey = info->src->colorkey;
+
+ if ( palmap ) {
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dst = palmap[*src];
+ }
+ dst++;
+ src++;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dst = *src;
+ }
+ dst++;
+ src++;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void Blit1to2Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint16 *palmap = (Uint16 *)info->table;
+ Uint32 ckey = info->src->colorkey;
+
+ /* Set up some basic variables */
+ dstskip /= 2;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dstp=palmap[*src];
+ }
+ src++;
+ dstp++;
+ },
+ width);
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void Blit1to3Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint8 *palmap = info->table;
+ Uint32 ckey = info->src->colorkey;
+ int o;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ o = *src * 4;
+ dst[0] = palmap[o++];
+ dst[1] = palmap[o++];
+ dst[2] = palmap[o++];
+ }
+ src++;
+ dst += 3;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void Blit1to4Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint32 *palmap = (Uint32 *)info->table;
+ Uint32 ckey = info->src->colorkey;
+
+ /* Set up some basic variables */
+ dstskip /= 4;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ *dstp = palmap[*src];
+ }
+ src++;
+ dstp++;
+ },
+ width);
+ src += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void Blit1toNAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *dstfmt = info->dst;
+ const SDL_Color *srcpal = info->src->palette->colors;
+ int dstbpp;
+ const int A = info->src->alpha;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+
+ while ( height-- ) {
+ int sR, sG, sB;
+ int dR, dG, dB;
+ DUFFS_LOOP4(
+ {
+ Uint32 pixel;
+ sR = srcpal[*src].r;
+ sG = srcpal[*src].g;
+ sB = srcpal[*src].b;
+ DISEMBLE_RGB(dst, dstbpp, dstfmt,
+ pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+ src++;
+ dst += dstbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void Blit1toNAlphaKey(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ const SDL_Color *srcpal = info->src->palette->colors;
+ Uint32 ckey = srcfmt->colorkey;
+ int dstbpp;
+ const int A = srcfmt->alpha;
+
+ /* Set up some basic variables */
+ dstbpp = dstfmt->BytesPerPixel;
+
+ while ( height-- ) {
+ int sR, sG, sB;
+ int dR, dG, dB;
+ DUFFS_LOOP(
+ {
+ if ( *src != ckey ) {
+ Uint32 pixel;
+ sR = srcpal[*src].r;
+ sG = srcpal[*src].g;
+ sB = srcpal[*src].b;
+ DISEMBLE_RGB(dst, dstbpp, dstfmt,
+ pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB);
+ }
+ src++;
+ dst += dstbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static SDL_loblit one_blit[] = {
+ NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
+};
+
+static SDL_loblit one_blitkey[] = {
+ NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
+};
+
+SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index)
+{
+ int which;
+ SDL_PixelFormat *dstfmt;
+
+ dstfmt = surface->map->dst->format;
+ if ( dstfmt->BitsPerPixel < 8 ) {
+ which = 0;
+ } else {
+ which = dstfmt->BytesPerPixel;
+ }
+ switch(blit_index) {
+ case 0: /* copy */
+ return one_blit[which];
+
+ case 1: /* colorkey */
+ return one_blitkey[which];
+
+ case 2: /* alpha */
+ /* Supporting 8bpp->8bpp alpha is doable but requires lots of
+ tables which consume space and takes time to precompute,
+ so is better left to the user */
+ return which >= 2 ? Blit1toNAlpha : NULL;
+
+ case 3: /* alpha + colorkey */
+ return which >= 2 ? Blit1toNAlphaKey : NULL;
+
+ }
+ return NULL;
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit_A.c b/distrib/sdl-1.2.15/src/video/SDL_blit_A.c
new file mode 100644
index 0000000..219cdcc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit_A.c
@@ -0,0 +1,2873 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/*
+ In Visual C, VC6 has mmintrin.h in the "Processor Pack" add-on.
+ Checking if _mm_free is #defined in malloc.h is is the only way to
+ determine if the Processor Pack is installed, as far as I can tell.
+*/
+
+#if SDL_ASSEMBLY_ROUTINES
+# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ /* forced MMX to 0...it breaks on most compilers now. --ryan. */
+# define MMX_ASMBLIT 0
+# define GCC_ASMBLIT 0
+# elif defined(_MSC_VER) && defined(_M_IX86)
+# if (_MSC_VER <= 1200)
+# include <malloc.h>
+# if defined(_mm_free)
+# define HAVE_MMINTRIN_H 1
+# endif
+# else /* Visual Studio > VC6 always has mmintrin.h */
+# define HAVE_MMINTRIN_H 1
+# endif
+# if HAVE_MMINTRIN_H
+# define MMX_ASMBLIT 1
+# define MSVC_ASMBLIT 1
+# endif
+# endif
+#endif /* SDL_ASSEMBLY_ROUTINES */
+
+/* Function to check the CPU flags */
+#include "SDL_cpuinfo.h"
+#if GCC_ASMBLIT
+#include "mmx.h"
+#elif MSVC_ASMBLIT
+#include <mmintrin.h>
+#include <mm3dnow.h>
+#endif
+
+/* Functions to perform alpha blended blitting */
+
+/* N->1 blending with per-surface alpha */
+static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+
+ const unsigned A = srcfmt->alpha;
+
+ while ( height-- ) {
+ DUFFS_LOOP4(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2))|
+ ((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2)) |
+ ((dB>>6)<<(0))];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* N->1 blending with pixel alpha */
+static void BlitNto1PixelAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+
+ /* FIXME: fix alpha bit field expansion here too? */
+ while ( height-- ) {
+ DUFFS_LOOP4(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned sA;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA);
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2))|
+ ((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2)) |
+ ((dB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* colorkeyed N->1 blending with per-surface alpha */
+static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint8 *palmap = info->table;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+ Uint32 ckey = srcfmt->colorkey;
+
+ const int A = srcfmt->alpha;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ if ( Pixel != ckey ) {
+ dR = dstfmt->palette->colors[*dst].r;
+ dG = dstfmt->palette->colors[*dst].g;
+ dB = dstfmt->palette->colors[*dst].b;
+ ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);
+ dR &= 0xff;
+ dG &= 0xff;
+ dB &= 0xff;
+ /* Pack RGB into 8bit pixel */
+ if ( palmap == NULL ) {
+ *dst =((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2)) |
+ ((dB>>6)<<(0));
+ } else {
+ *dst = palmap[((dR>>5)<<(3+2))|
+ ((dG>>5)<<(2)) |
+ ((dB>>6)<<(0)) ];
+ }
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+#if GCC_ASMBLIT
+/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
+static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ Uint32 dalpha = info->dst->Amask;
+ Uint64 load;
+
+ load = 0x00fefefe00fefefeULL;/* alpha128 mask */
+ movq_m2r(load, mm4); /* alpha128 mask -> mm4 */
+ load = 0x0001010100010101ULL;/* !alpha128 mask */
+ movq_m2r(load, mm3); /* !alpha128 mask -> mm3 */
+ movd_m2r(dalpha, mm7); /* dst alpha mask */
+ punpckldq_r2r(mm7, mm7); /* dst alpha mask | dst alpha mask -> mm7 */
+ while(height--) {
+ DUFFS_LOOP_DOUBLE2(
+ {
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+ + (s & d & 0x00010101)) | dalpha;
+ },{
+ movq_m2r((*dstp), mm2);/* 2 x dst -> mm2(ARGBARGB) */
+ movq_r2r(mm2, mm6); /* 2 x dst -> mm6(ARGBARGB) */
+
+ movq_m2r((*srcp), mm1);/* 2 x src -> mm1(ARGBARGB) */
+ movq_r2r(mm1, mm5); /* 2 x src -> mm5(ARGBARGB) */
+
+ pand_r2r(mm4, mm6); /* dst & mask -> mm6 */
+ pand_r2r(mm4, mm5); /* src & mask -> mm5 */
+ paddd_r2r(mm6, mm5); /* mm6 + mm5 -> mm5 */
+ pand_r2r(mm1, mm2); /* src & dst -> mm2 */
+ psrld_i2r(1, mm5); /* mm5 >> 1 -> mm5 */
+ pand_r2r(mm3, mm2); /* mm2 & !mask -> mm2 */
+ paddd_r2r(mm5, mm2); /* mm5 + mm2 -> mm2 */
+
+ por_r2r(mm7, mm2); /* mm7(full alpha) | mm2 -> mm2 */
+ movq_r2m(mm2, (*dstp));/* mm2 -> 2 x dst pixels */
+ dstp += 2;
+ srcp += 2;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ emms();
+}
+
+/* fast RGB888->(A)RGB888 blending with surface alpha */
+static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ SDL_PixelFormat* df = info->dst;
+ unsigned alpha = info->src->alpha;
+
+ if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) {
+ /* only call a128 version when R,G,B occupy lower bits */
+ BlitRGBtoRGBSurfaceAlpha128MMX(info);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+
+ pxor_r2r(mm5, mm5); /* 0 -> mm5 */
+ /* form the alpha mult */
+ movd_m2r(alpha, mm4); /* 0000000A -> mm4 */
+ punpcklwd_r2r(mm4, mm4); /* 00000A0A -> mm4 */
+ punpckldq_r2r(mm4, mm4); /* 0A0A0A0A -> mm4 */
+ alpha = (0xff << df->Rshift) | (0xff << df->Gshift) | (0xff << df->Bshift);
+ movd_m2r(alpha, mm0); /* 00000FFF -> mm0 */
+ punpcklbw_r2r(mm0, mm0); /* 00FFFFFF -> mm0 */
+ pand_r2r(mm0, mm4); /* 0A0A0A0A -> mm4, minus 1 chan */
+ /* at this point mm4 can be 000A0A0A or 0A0A0A00 or another combo */
+ movd_m2r(df->Amask, mm7); /* dst alpha mask */
+ punpckldq_r2r(mm7, mm7); /* dst alpha mask | dst alpha mask -> mm7 */
+
+ while(height--) {
+ DUFFS_LOOP_DOUBLE2({
+ /* One Pixel Blend */
+ movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/
+ movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/
+ punpcklbw_r2r(mm5, mm1); /* 0A0R0G0B -> mm1(src) */
+ punpcklbw_r2r(mm5, mm2); /* 0A0R0G0B -> mm2(dst) */
+
+ psubw_r2r(mm2, mm1);/* src - dst -> mm1 */
+ pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */
+ psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1 */
+ paddb_r2r(mm1, mm2); /* mm1 + mm2(dst) -> mm2 */
+
+ packuswb_r2r(mm5, mm2); /* ARGBARGB -> mm2 */
+ por_r2r(mm7, mm2); /* mm7(full alpha) | mm2 -> mm2 */
+ movd_r2m(mm2, *dstp);/* mm2 -> pixel */
+ ++srcp;
+ ++dstp;
+ },{
+ /* Two Pixels Blend */
+ movq_m2r((*srcp), mm0);/* 2 x src -> mm0(ARGBARGB)*/
+ movq_m2r((*dstp), mm2);/* 2 x dst -> mm2(ARGBARGB) */
+ movq_r2r(mm0, mm1); /* 2 x src -> mm1(ARGBARGB) */
+ movq_r2r(mm2, mm6); /* 2 x dst -> mm6(ARGBARGB) */
+
+ punpcklbw_r2r(mm5, mm0); /* low - 0A0R0G0B -> mm0(src1) */
+ punpckhbw_r2r(mm5, mm1); /* high - 0A0R0G0B -> mm1(src2) */
+ punpcklbw_r2r(mm5, mm2); /* low - 0A0R0G0B -> mm2(dst1) */
+ punpckhbw_r2r(mm5, mm6); /* high - 0A0R0G0B -> mm6(dst2) */
+
+ psubw_r2r(mm2, mm0);/* src1 - dst1 -> mm0 */
+ pmullw_r2r(mm4, mm0); /* mm0 * alpha -> mm0 */
+ psrlw_i2r(8, mm0); /* mm0 >> 8 -> mm1 */
+ paddb_r2r(mm0, mm2); /* mm0 + mm2(dst1) -> mm2 */
+
+ psubw_r2r(mm6, mm1);/* src2 - dst2 -> mm1 */
+ pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */
+ psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1 */
+ paddb_r2r(mm1, mm6); /* mm1 + mm6(dst2) -> mm6 */
+
+ packuswb_r2r(mm6, mm2); /* ARGBARGB -> mm2 */
+ por_r2r(mm7, mm2); /* mm7(dst alpha) | mm2 -> mm2 */
+
+ movq_r2m(mm2, *dstp);/* mm2 -> 2 x pixel */
+
+ srcp += 2;
+ dstp += 2;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ emms();
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat* sf = info->src;
+ Uint32 amask = sf->Amask;
+
+ pxor_r2r(mm6, mm6); /* 0 -> mm6 */
+ /* form multiplication mask */
+ movd_m2r(sf->Amask, mm7); /* 0000F000 -> mm7 */
+ punpcklbw_r2r(mm7, mm7); /* FF000000 -> mm7 */
+ pcmpeqb_r2r(mm0, mm0); /* FFFFFFFF -> mm0 */
+ movq_r2r(mm0, mm3); /* FFFFFFFF -> mm3 (for later) */
+ pxor_r2r(mm0, mm7); /* 00FFFFFF -> mm7 (mult mask) */
+ /* form channel masks */
+ movq_r2r(mm7, mm0); /* 00FFFFFF -> mm0 */
+ packsswb_r2r(mm6, mm0); /* 00000FFF -> mm0 (channel mask) */
+ packsswb_r2r(mm6, mm3); /* 0000FFFF -> mm3 */
+ pxor_r2r(mm0, mm3); /* 0000F000 -> mm3 (~channel mask) */
+ /* get alpha channel shift */
+ __asm__ __volatile__ (
+ "movd %0, %%mm5"
+ : : "rm" ((Uint32) sf->Ashift) ); /* Ashift -> mm5 */
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 alpha = *srcp & amask;
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha == 0) {
+ /* do nothing */
+ } else if(alpha == amask) {
+ /* opaque alpha -- copy RGB, keep dst alpha */
+ /* using MMX here to free up regular registers for other things */
+ movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/
+ movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/
+ pand_r2r(mm0, mm1); /* src & chanmask -> mm1 */
+ pand_r2r(mm3, mm2); /* dst & ~chanmask -> mm2 */
+ por_r2r(mm1, mm2); /* src | dst -> mm2 */
+ movd_r2m(mm2, (*dstp)); /* mm2 -> dst */
+ } else {
+ movd_m2r((*srcp), mm1);/* src(ARGB) -> mm1 (0000ARGB)*/
+ punpcklbw_r2r(mm6, mm1); /* 0A0R0G0B -> mm1 */
+
+ movd_m2r((*dstp), mm2);/* dst(ARGB) -> mm2 (0000ARGB)*/
+ punpcklbw_r2r(mm6, mm2); /* 0A0R0G0B -> mm2 */
+
+ __asm__ __volatile__ (
+ "movd %0, %%mm4"
+ : : "r" (alpha) ); /* 0000A000 -> mm4 */
+ psrld_r2r(mm5, mm4); /* mm4 >> mm5 -> mm4 (0000000A) */
+ punpcklwd_r2r(mm4, mm4); /* 00000A0A -> mm4 */
+ punpcklwd_r2r(mm4, mm4); /* 0A0A0A0A -> mm4 */
+ pand_r2r(mm7, mm4); /* 000A0A0A -> mm4, preserve dst alpha on add */
+
+ /* blend */
+ psubw_r2r(mm2, mm1);/* src - dst -> mm1 */
+ pmullw_r2r(mm4, mm1); /* mm1 * alpha -> mm1 */
+ psrlw_i2r(8, mm1); /* mm1 >> 8 -> mm1(000R0G0B) */
+ paddb_r2r(mm1, mm2); /* mm1 + mm2(dst) -> mm2 */
+
+ packuswb_r2r(mm6, mm2); /* 0000ARGB -> mm2 */
+ movd_r2m(mm2, *dstp);/* mm2 -> dst */
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ emms();
+}
+/* End GCC_ASMBLIT */
+
+#elif MSVC_ASMBLIT
+/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
+static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ Uint32 dalpha = info->dst->Amask;
+
+ __m64 src1, src2, dst1, dst2, lmask, hmask, dsta;
+
+ hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */
+ lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */
+ dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */
+
+ while (height--) {
+ int n = width;
+ if ( n & 1 ) {
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+ + (s & d & 0x00010101)) | dalpha;
+ n--;
+ }
+
+ for (n >>= 1; n > 0; --n) {
+ dst1 = *(__m64*)dstp; /* 2 x dst -> dst1(ARGBARGB) */
+ dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */
+
+ src1 = *(__m64*)srcp; /* 2 x src -> src1(ARGBARGB) */
+ src2 = src1; /* 2 x src -> src2(ARGBARGB) */
+
+ dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */
+ src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */
+ src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */
+ src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */
+
+ dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */
+ dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */
+ dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */
+
+ *(__m64*)dstp = dst1; /* dst1 -> 2 x dst pixels */
+ dstp += 2;
+ srcp += 2;
+ }
+
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+
+/* fast RGB888->(A)RGB888 blending with surface alpha */
+static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ SDL_PixelFormat* df = info->dst;
+ Uint32 chanmask = df->Rmask | df->Gmask | df->Bmask;
+ unsigned alpha = info->src->alpha;
+
+ if (alpha == 128 && (df->Rmask | df->Gmask | df->Bmask) == 0x00FFFFFF) {
+ /* only call a128 version when R,G,B occupy lower bits */
+ BlitRGBtoRGBSurfaceAlpha128MMX(info);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ Uint32 dalpha = df->Amask;
+ Uint32 amult;
+
+ __m64 src1, src2, dst1, dst2, mm_alpha, mm_zero, dsta;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ /* form the alpha mult */
+ amult = alpha | (alpha << 8);
+ amult = amult | (amult << 16);
+ chanmask = (0xff << df->Rshift) | (0xff << df->Gshift) | (0xff << df->Bshift);
+ mm_alpha = _mm_set_pi32(0, amult & chanmask); /* 0000AAAA -> mm_alpha, minus 1 chan */
+ mm_alpha = _mm_unpacklo_pi8(mm_alpha, mm_zero); /* 0A0A0A0A -> mm_alpha, minus 1 chan */
+ /* at this point mm_alpha can be 000A0A0A or 0A0A0A00 or another combo */
+ dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */
+
+ while (height--) {
+ int n = width;
+ if (n & 1) {
+ /* One Pixel Blend */
+ src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB)*/
+ src2 = _mm_unpacklo_pi8(src2, mm_zero); /* 0A0R0G0B -> src2 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */
+ dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */
+
+ dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+
+ ++srcp;
+ ++dstp;
+
+ n--;
+ }
+
+ for (n >>= 1; n > 0; --n) {
+ /* Two Pixels Blend */
+ src1 = *(__m64*)srcp; /* 2 x src -> src1(ARGBARGB)*/
+ src2 = src1; /* 2 x src -> src2(ARGBARGB) */
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* low - 0A0R0G0B -> src1 */
+ src2 = _mm_unpackhi_pi8(src2, mm_zero); /* high - 0A0R0G0B -> src2 */
+
+ dst1 = *(__m64*)dstp;/* 2 x dst -> dst1(ARGBARGB) */
+ dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* low - 0A0R0G0B -> dst1 */
+ dst2 = _mm_unpackhi_pi8(dst2, mm_zero); /* high - 0A0R0G0B -> dst2 */
+
+ src1 = _mm_sub_pi16(src1, dst1);/* src1 - dst1 -> src1 */
+ src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */
+ src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */
+ dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */
+
+ src2 = _mm_sub_pi16(src2, dst2);/* src2 - dst2 -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */
+ dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */
+
+ dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */
+ dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */
+
+ *(__m64*)dstp = dst1; /* dst1 -> 2 x pixel */
+
+ srcp += 2;
+ dstp += 2;
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat* sf = info->src;
+ Uint32 chanmask = sf->Rmask | sf->Gmask | sf->Bmask;
+ Uint32 amask = sf->Amask;
+ Uint32 ashift = sf->Ashift;
+ Uint64 multmask;
+
+ __m64 src1, dst1, mm_alpha, mm_zero, dmask;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ multmask = ~(0xFFFFi64 << (ashift * 2));
+ dmask = *(__m64*) &multmask; /* dst alpha mask -> dmask */
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 alpha = *srcp & amask;
+ if (alpha == 0) {
+ /* do nothing */
+ } else if (alpha == amask) {
+ /* opaque alpha -- copy RGB, keep dst alpha */
+ *dstp = (*srcp & chanmask) | (*dstp & ~chanmask);
+ } else {
+ src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB)*/
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */
+ mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ mm_alpha = _mm_and_si64(mm_alpha, dmask); /* 000A0A0A -> mm_alpha, preserve dst alpha on add */
+
+ /* blend */
+ src1 = _mm_sub_pi16(src1, dst1);/* src1 - dst1 -> src1 */
+ src1 = _mm_mullo_pi16(src1, mm_alpha); /* (src1 - dst1) * alpha -> src1 */
+ src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1(000R0G0B) */
+ dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1 -> dst1(0A0R0G0B) */
+ dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */
+
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+/* End MSVC_ASMBLIT */
+
+#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */
+
+#if SDL_ALTIVEC_BLITTERS
+#if __MWERKS__
+#pragma altivec_model on
+#endif
+#if HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+#include <assert.h>
+
+#if (defined(__MACOSX__) && (__GNUC__ < 4))
+ #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
+ #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) ( a,b,c,d,e,f,g,h )
+#else
+ #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
+ #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) { a,b,c,d,e,f,g,h }
+#endif
+
+#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
+#define VECPRINT(msg, v) do { \
+ vector unsigned int tmpvec = (vector unsigned int)(v); \
+ unsigned int *vp = (unsigned int *)&tmpvec; \
+ printf("%s = %08X %08X %08X %08X\n", msg, vp[0], vp[1], vp[2], vp[3]); \
+} while (0)
+
+/* the permuation vector that takes the high bytes out of all the appropriate shorts
+ (vector unsigned char)(
+ 0x00, 0x10, 0x02, 0x12,
+ 0x04, 0x14, 0x06, 0x16,
+ 0x08, 0x18, 0x0A, 0x1A,
+ 0x0C, 0x1C, 0x0E, 0x1E );
+*/
+#define VEC_MERGE_PERMUTE() (vec_add(vec_lvsl(0, (int*)NULL), (vector unsigned char)vec_splat_u16(0x0F)))
+#define VEC_U32_24() (vec_add(vec_splat_u32(12), vec_splat_u32(12)))
+#define VEC_ALPHA_MASK() ((vector unsigned char)vec_sl((vector unsigned int)vec_splat_s8(-1), VEC_U32_24()))
+#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
+ ? vec_lvsl(0, src) \
+ : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
+
+
+#define VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1_16, v8_16) do { \
+ /* vtemp1 contains source AAGGAAGGAAGGAAGG */ \
+ vector unsigned short vtemp1 = vec_mule(vs, valpha); \
+ /* vtemp2 contains source RRBBRRBBRRBBRRBB */ \
+ vector unsigned short vtemp2 = vec_mulo(vs, valpha); \
+ /* valpha2 is 255-alpha */ \
+ vector unsigned char valpha2 = vec_nor(valpha, valpha); \
+ /* vtemp3 contains dest AAGGAAGGAAGGAAGG */ \
+ vector unsigned short vtemp3 = vec_mule(vd, valpha2); \
+ /* vtemp4 contains dest RRBBRRBBRRBBRRBB */ \
+ vector unsigned short vtemp4 = vec_mulo(vd, valpha2); \
+ /* add source and dest */ \
+ vtemp1 = vec_add(vtemp1, vtemp3); \
+ vtemp2 = vec_add(vtemp2, vtemp4); \
+ /* vtemp1 = (vtemp1 + 1) + ((vtemp1 + 1) >> 8) */ \
+ vtemp1 = vec_add(vtemp1, v1_16); \
+ vtemp3 = vec_sr(vtemp1, v8_16); \
+ vtemp1 = vec_add(vtemp1, vtemp3); \
+ /* vtemp2 = (vtemp2 + 1) + ((vtemp2 + 1) >> 8) */ \
+ vtemp2 = vec_add(vtemp2, v1_16); \
+ vtemp4 = vec_sr(vtemp2, v8_16); \
+ vtemp2 = vec_add(vtemp2, vtemp4); \
+ /* (>>8) and get ARGBARGBARGBARGB */ \
+ vd = (vector unsigned char)vec_perm(vtemp1, vtemp2, mergePermute); \
+} while (0)
+
+/* Calculate the permute vector used for 32->32 swizzling */
+static vector unsigned char calc_swizzle32(const SDL_PixelFormat *srcfmt,
+ const SDL_PixelFormat *dstfmt)
+{
+ /*
+ * We have to assume that the bits that aren't used by other
+ * colors is alpha, and it's one complete byte, since some formats
+ * leave alpha with a zero mask, but we should still swizzle the bits.
+ */
+ /* ARGB */
+ const static struct SDL_PixelFormat default_pixel_format = {
+ NULL, 0, 0,
+ 0, 0, 0, 0,
+ 16, 8, 0, 24,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
+ 0, 0};
+ if (!srcfmt) {
+ srcfmt = &default_pixel_format;
+ }
+ if (!dstfmt) {
+ dstfmt = &default_pixel_format;
+ }
+ const vector unsigned char plus = VECUINT8_LITERAL
+ ( 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x04, 0x04, 0x04,
+ 0x08, 0x08, 0x08, 0x08,
+ 0x0C, 0x0C, 0x0C, 0x0C );
+ vector unsigned char vswiz;
+ vector unsigned int srcvec;
+#define RESHIFT(X) (3 - ((X) >> 3))
+ Uint32 rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
+ Uint32 gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
+ Uint32 bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
+ Uint32 amask;
+ /* Use zero for alpha if either surface doesn't have alpha */
+ if (dstfmt->Amask) {
+ amask = ((srcfmt->Amask) ? RESHIFT(srcfmt->Ashift) : 0x10) << (dstfmt->Ashift);
+ } else {
+ amask = 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^ 0xFFFFFFFF);
+ }
+#undef RESHIFT
+ ((unsigned int *)(char*)&srcvec)[0] = (rmask | gmask | bmask | amask);
+ vswiz = vec_add(plus, (vector unsigned char)vec_splat(srcvec, 0));
+ return(vswiz);
+}
+
+static void Blit32to565PixelAlphaAltivec(SDL_BlitInfo *info)
+{
+ int height = info->d_height;
+ Uint8 *src = (Uint8 *)info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = (Uint8 *)info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+
+ vector unsigned char v0 = vec_splat_u8(0);
+ vector unsigned short v8_16 = vec_splat_u16(8);
+ vector unsigned short v1_16 = vec_splat_u16(1);
+ vector unsigned short v2_16 = vec_splat_u16(2);
+ vector unsigned short v3_16 = vec_splat_u16(3);
+ vector unsigned int v8_32 = vec_splat_u32(8);
+ vector unsigned int v16_32 = vec_add(v8_32, v8_32);
+ vector unsigned short v3f = VECUINT16_LITERAL(
+ 0x003f, 0x003f, 0x003f, 0x003f,
+ 0x003f, 0x003f, 0x003f, 0x003f);
+ vector unsigned short vfc = VECUINT16_LITERAL(
+ 0x00fc, 0x00fc, 0x00fc, 0x00fc,
+ 0x00fc, 0x00fc, 0x00fc, 0x00fc);
+
+ /*
+ 0x10 - 0x1f is the alpha
+ 0x00 - 0x0e evens are the red
+ 0x01 - 0x0f odds are zero
+ */
+ vector unsigned char vredalpha1 = VECUINT8_LITERAL(
+ 0x10, 0x00, 0x01, 0x01,
+ 0x10, 0x02, 0x01, 0x01,
+ 0x10, 0x04, 0x01, 0x01,
+ 0x10, 0x06, 0x01, 0x01
+ );
+ vector unsigned char vredalpha2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vredalpha1, vec_sl(v8_32, v16_32))
+ );
+ /*
+ 0x00 - 0x0f is ARxx ARxx ARxx ARxx
+ 0x11 - 0x0f odds are blue
+ */
+ vector unsigned char vblue1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x02, 0x11,
+ 0x04, 0x05, 0x06, 0x13,
+ 0x08, 0x09, 0x0a, 0x15,
+ 0x0c, 0x0d, 0x0e, 0x17
+ );
+ vector unsigned char vblue2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vblue1, v8_32)
+ );
+ /*
+ 0x00 - 0x0f is ARxB ARxB ARxB ARxB
+ 0x10 - 0x0e evens are green
+ */
+ vector unsigned char vgreen1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x10, 0x03,
+ 0x04, 0x05, 0x12, 0x07,
+ 0x08, 0x09, 0x14, 0x0b,
+ 0x0c, 0x0d, 0x16, 0x0f
+ );
+ vector unsigned char vgreen2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vgreen1, vec_sl(v8_32, v8_32))
+ );
+ vector unsigned char vgmerge = VECUINT8_LITERAL(
+ 0x00, 0x02, 0x00, 0x06,
+ 0x00, 0x0a, 0x00, 0x0e,
+ 0x00, 0x12, 0x00, 0x16,
+ 0x00, 0x1a, 0x00, 0x1e);
+ vector unsigned char mergePermute = VEC_MERGE_PERMUTE();
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
+ vector unsigned char valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC));
+
+ vector unsigned short vf800 = (vector unsigned short)vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ while(height--) {
+ int extrawidth;
+ vector unsigned char valigner;
+ vector unsigned char vsrc;
+ vector unsigned char voverflow;
+ int width = info->d_width;
+
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, dR, dG, dB, sA; \
+ DISEMBLE_RGBA(src, 4, srcfmt, Pixel, sR, sG, sB, sA); \
+ if(sA) { \
+ unsigned short dstpixel = *((unsigned short *)dst); \
+ dR = (dstpixel >> 8) & 0xf8; \
+ dG = (dstpixel >> 3) & 0xfc; \
+ dB = (dstpixel << 3) & 0xf8; \
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \
+ *((unsigned short *)dst) = ( \
+ ((dR & 0xf8) << 8) | ((dG & 0xfc) << 3) | (dB >> 3) \
+ ); \
+ } \
+ src += 4; \
+ dst += 2; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dst)) && (width), width);
+ extrawidth = (width % 8);
+ valigner = VEC_ALIGNER(src);
+ vsrc = (vector unsigned char)vec_ld(0, src);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char valpha;
+ vector unsigned char vsrc1, vsrc2;
+ vector unsigned char vdst1, vdst2;
+ vector unsigned short vR, vG, vB;
+ vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
+
+ /* Load 8 pixels from src as ARGB */
+ voverflow = (vector unsigned char)vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+ vsrc1 = vec_perm(vsrc, vsrc, vpermute);
+ src += 16;
+ vsrc = (vector unsigned char)vec_ld(15, src);
+ voverflow = vec_perm(voverflow, vsrc, valigner);
+ vsrc2 = vec_perm(voverflow, voverflow, vpermute);
+ src += 16;
+
+ /* Load 8 pixels from dst as XRGB */
+ voverflow = vec_ld(0, dst);
+ vR = vec_and((vector unsigned short)voverflow, vf800);
+ vB = vec_sl((vector unsigned short)voverflow, v3_16);
+ vG = vec_sl(vB, v2_16);
+ vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, (vector unsigned char)vR, vredalpha1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1);
+ vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, (vector unsigned char)vR, vredalpha2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2);
+
+ /* Alpha blend 8 pixels as ARGB */
+ valpha = vec_perm(vsrc1, v0, valphaPermute);
+ VEC_MULTIPLY_ALPHA(vsrc1, vdst1, valpha, mergePermute, v1_16, v8_16);
+ valpha = vec_perm(vsrc2, v0, valphaPermute);
+ VEC_MULTIPLY_ALPHA(vsrc2, vdst2, valpha, mergePermute, v1_16, v8_16);
+
+ /* Convert 8 pixels to 565 */
+ vpixel = (vector unsigned short)vec_packpx((vector unsigned int)vdst1, (vector unsigned int)vdst2);
+ vgpixel = (vector unsigned short)vec_perm(vdst1, vdst2, vgmerge);
+ vgpixel = vec_and(vgpixel, vfc);
+ vgpixel = vec_sl(vgpixel, v3_16);
+ vrpixel = vec_sl(vpixel, v1_16);
+ vrpixel = vec_and(vrpixel, vf800);
+ vbpixel = vec_and(vpixel, v3f);
+ vdst1 = vec_or((vector unsigned char)vrpixel, (vector unsigned char)vgpixel);
+ vdst1 = vec_or(vdst1, (vector unsigned char)vbpixel);
+
+ /* Store 8 pixels */
+ vec_st(vdst1, 0, dst);
+
+ width -= 8;
+ dst += 16;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void Blit32to32SurfaceAlphaKeyAltivec(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ unsigned sA = srcfmt->alpha;
+ unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+ Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
+ Uint32 ckey = info->src->colorkey;
+ vector unsigned char mergePermute;
+ vector unsigned char vsrcPermute;
+ vector unsigned char vdstPermute;
+ vector unsigned char vsdstPermute;
+ vector unsigned char valpha;
+ vector unsigned char valphamask;
+ vector unsigned char vbits;
+ vector unsigned char v0;
+ vector unsigned short v1;
+ vector unsigned short v8;
+ vector unsigned int vckey;
+ vector unsigned int vrgbmask;
+
+ mergePermute = VEC_MERGE_PERMUTE();
+ v0 = vec_splat_u8(0);
+ v1 = vec_splat_u16(1);
+ v8 = vec_splat_u16(8);
+
+ /* set the alpha to 255 on the destination surf */
+ valphamask = VEC_ALPHA_MASK();
+
+ vsrcPermute = calc_swizzle32(srcfmt, NULL);
+ vdstPermute = calc_swizzle32(NULL, dstfmt);
+ vsdstPermute = calc_swizzle32(dstfmt, NULL);
+
+ /* set a vector full of alpha and 255-alpha */
+ ((unsigned char *)&valpha)[0] = alpha;
+ valpha = vec_splat(valpha, 0);
+ vbits = (vector unsigned char)vec_splat_s8(-1);
+
+ ckey &= rgbmask;
+ ((unsigned int *)(char*)&vckey)[0] = ckey;
+ vckey = vec_splat(vckey, 0);
+ ((unsigned int *)(char*)&vrgbmask)[0] = rgbmask;
+ vrgbmask = vec_splat(vrgbmask, 0);
+
+ while(height--) {
+ int width = info->d_width;
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, dR, dG, dB; \
+ RETRIEVE_RGB_PIXEL(((Uint8 *)srcp), 4, Pixel); \
+ if(sA && Pixel != ckey) { \
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
+ DISEMBLE_RGB(((Uint8 *)dstp), 4, dstfmt, Pixel, dR, dG, dB); \
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \
+ ASSEMBLE_RGBA(((Uint8 *)dstp), 4, dstfmt, dR, dG, dB, dA); \
+ } \
+ dstp++; \
+ srcp++; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char vsel;
+ vector unsigned char voverflow;
+ vector unsigned char vd;
+ vector unsigned char vd_orig;
+
+ /* s = *srcp */
+ voverflow = (vector unsigned char)vec_ld(15, srcp);
+ vs = vec_perm(vs, voverflow, valigner);
+
+ /* vsel is set for items that match the key */
+ vsel = (vector unsigned char)vec_and((vector unsigned int)vs, vrgbmask);
+ vsel = (vector unsigned char)vec_cmpeq((vector unsigned int)vsel, vckey);
+
+ /* permute to source format */
+ vs = vec_perm(vs, valpha, vsrcPermute);
+
+ /* d = *dstp */
+ vd = (vector unsigned char)vec_ld(0, dstp);
+ vd_orig = vd = vec_perm(vd, v0, vsdstPermute);
+
+ VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8);
+
+ /* set the alpha channel to full on */
+ vd = vec_or(vd, valphamask);
+
+ /* mask out color key */
+ vd = vec_sel(vd, vd_orig, vsel);
+
+ /* permute to dest format */
+ vd = vec_perm(vd, vbits, vdstPermute);
+
+ /* *dstp = res */
+ vec_st((vector unsigned int)vd, 0, dstp);
+
+ srcp += 4;
+ dstp += 4;
+ width -= 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+ }
+#undef ONE_PIXEL_BLEND
+
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+
+static void Blit32to32PixelAlphaAltivec(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ vector unsigned char mergePermute;
+ vector unsigned char valphaPermute;
+ vector unsigned char vsrcPermute;
+ vector unsigned char vdstPermute;
+ vector unsigned char vsdstPermute;
+ vector unsigned char valphamask;
+ vector unsigned char vpixelmask;
+ vector unsigned char v0;
+ vector unsigned short v1;
+ vector unsigned short v8;
+
+ v0 = vec_splat_u8(0);
+ v1 = vec_splat_u16(1);
+ v8 = vec_splat_u16(8);
+ mergePermute = VEC_MERGE_PERMUTE();
+ valphamask = VEC_ALPHA_MASK();
+ valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC));
+ vpixelmask = vec_nor(valphamask, v0);
+ vsrcPermute = calc_swizzle32(srcfmt, NULL);
+ vdstPermute = calc_swizzle32(NULL, dstfmt);
+ vsdstPermute = calc_swizzle32(dstfmt, NULL);
+
+ while ( height-- ) {
+ width = info->d_width;
+#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, dR, dG, dB, sA, dA; \
+ DISEMBLE_RGBA((Uint8 *)srcp, 4, srcfmt, Pixel, sR, sG, sB, sA); \
+ if(sA) { \
+ DISEMBLE_RGBA((Uint8 *)dstp, 4, dstfmt, Pixel, dR, dG, dB, dA); \
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \
+ ASSEMBLE_RGBA((Uint8 *)dstp, 4, dstfmt, dR, dG, dB, dA); \
+ } \
+ ++srcp; \
+ ++dstp; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ if (width > 0) {
+ /* vsrcPermute */
+ /* vdstPermute */
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char voverflow;
+ vector unsigned char vd;
+ vector unsigned char valpha;
+ vector unsigned char vdstalpha;
+ /* s = *srcp */
+ voverflow = (vector unsigned char)vec_ld(15, srcp);
+ vs = vec_perm(vs, voverflow, valigner);
+ vs = vec_perm(vs, v0, vsrcPermute);
+
+ valpha = vec_perm(vs, v0, valphaPermute);
+
+ /* d = *dstp */
+ vd = (vector unsigned char)vec_ld(0, dstp);
+ vd = vec_perm(vd, v0, vsdstPermute);
+ vdstalpha = vec_and(vd, valphamask);
+
+ VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8);
+
+ /* set the alpha to the dest alpha */
+ vd = vec_and(vd, vpixelmask);
+ vd = vec_or(vd, vdstalpha);
+ vd = vec_perm(vd, v0, vdstPermute);
+
+ /* *dstp = res */
+ vec_st((vector unsigned int)vd, 0, dstp);
+
+ srcp += 4;
+ dstp += 4;
+ width -= 4;
+ vs = voverflow;
+
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+#undef ONE_PIXEL_BLEND
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlphaAltivec(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ vector unsigned char mergePermute;
+ vector unsigned char valphaPermute;
+ vector unsigned char valphamask;
+ vector unsigned char vpixelmask;
+ vector unsigned char v0;
+ vector unsigned short v1;
+ vector unsigned short v8;
+ v0 = vec_splat_u8(0);
+ v1 = vec_splat_u16(1);
+ v8 = vec_splat_u16(8);
+ mergePermute = VEC_MERGE_PERMUTE();
+ valphamask = VEC_ALPHA_MASK();
+ valphaPermute = vec_and(vec_lvsl(0, (int *)NULL), vec_splat_u8(0xC));
+
+
+ vpixelmask = vec_nor(valphamask, v0);
+ while(height--) {
+ width = info->d_width;
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while ((condition)) { \
+ Uint32 dalpha; \
+ Uint32 d; \
+ Uint32 s1; \
+ Uint32 d1; \
+ Uint32 s = *srcp; \
+ Uint32 alpha = s >> 24; \
+ if(alpha) { \
+ if(alpha == SDL_ALPHA_OPAQUE) { \
+ *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); \
+ } else { \
+ d = *dstp; \
+ dalpha = d & 0xff000000; \
+ s1 = s & 0xff00ff; \
+ d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ *dstp = d1 | d | dalpha; \
+ } \
+ } \
+ ++srcp; \
+ ++dstp; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char voverflow;
+ vector unsigned char vd;
+ vector unsigned char valpha;
+ vector unsigned char vdstalpha;
+ /* s = *srcp */
+ voverflow = (vector unsigned char)vec_ld(15, srcp);
+ vs = vec_perm(vs, voverflow, valigner);
+
+ valpha = vec_perm(vs, v0, valphaPermute);
+
+ /* d = *dstp */
+ vd = (vector unsigned char)vec_ld(0, dstp);
+ vdstalpha = vec_and(vd, valphamask);
+
+ VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8);
+
+ /* set the alpha to the dest alpha */
+ vd = vec_and(vd, vpixelmask);
+ vd = vec_or(vd, vdstalpha);
+
+ /* *dstp = res */
+ vec_st((vector unsigned int)vd, 0, dstp);
+
+ srcp += 4;
+ dstp += 4;
+ width -= 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+#undef ONE_PIXEL_BLEND
+}
+
+static void Blit32to32SurfaceAlphaAltivec(SDL_BlitInfo *info)
+{
+ /* XXX : 6 */
+ unsigned alpha = info->src->alpha;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ unsigned sA = srcfmt->alpha;
+ unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+ vector unsigned char mergePermute;
+ vector unsigned char vsrcPermute;
+ vector unsigned char vdstPermute;
+ vector unsigned char vsdstPermute;
+ vector unsigned char valpha;
+ vector unsigned char valphamask;
+ vector unsigned char vbits;
+ vector unsigned short v1;
+ vector unsigned short v8;
+
+ mergePermute = VEC_MERGE_PERMUTE();
+ v1 = vec_splat_u16(1);
+ v8 = vec_splat_u16(8);
+
+ /* set the alpha to 255 on the destination surf */
+ valphamask = VEC_ALPHA_MASK();
+
+ vsrcPermute = calc_swizzle32(srcfmt, NULL);
+ vdstPermute = calc_swizzle32(NULL, dstfmt);
+ vsdstPermute = calc_swizzle32(dstfmt, NULL);
+
+ /* set a vector full of alpha and 255-alpha */
+ ((unsigned char *)&valpha)[0] = alpha;
+ valpha = vec_splat(valpha, 0);
+ vbits = (vector unsigned char)vec_splat_s8(-1);
+
+ while(height--) {
+ int width = info->d_width;
+#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, dR, dG, dB; \
+ DISEMBLE_RGB(((Uint8 *)srcp), 4, srcfmt, Pixel, sR, sG, sB); \
+ DISEMBLE_RGB(((Uint8 *)dstp), 4, dstfmt, Pixel, dR, dG, dB); \
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); \
+ ASSEMBLE_RGBA(((Uint8 *)dstp), 4, dstfmt, dR, dG, dB, dA); \
+ ++srcp; \
+ ++dstp; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char voverflow;
+ vector unsigned char vd;
+
+ /* s = *srcp */
+ voverflow = (vector unsigned char)vec_ld(15, srcp);
+ vs = vec_perm(vs, voverflow, valigner);
+ vs = vec_perm(vs, valpha, vsrcPermute);
+
+ /* d = *dstp */
+ vd = (vector unsigned char)vec_ld(0, dstp);
+ vd = vec_perm(vd, vd, vsdstPermute);
+
+ VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8);
+
+ /* set the alpha channel to full on */
+ vd = vec_or(vd, valphamask);
+ vd = vec_perm(vd, vbits, vdstPermute);
+
+ /* *dstp = res */
+ vec_st((vector unsigned int)vd, 0, dstp);
+
+ srcp += 4;
+ dstp += 4;
+ width -= 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+ }
+#undef ONE_PIXEL_BLEND
+
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+
+}
+
+
+/* fast RGB888->(A)RGB888 blending */
+static void BlitRGBtoRGBSurfaceAlphaAltivec(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ vector unsigned char mergePermute;
+ vector unsigned char valpha;
+ vector unsigned char valphamask;
+ vector unsigned short v1;
+ vector unsigned short v8;
+
+ mergePermute = VEC_MERGE_PERMUTE();
+ v1 = vec_splat_u16(1);
+ v8 = vec_splat_u16(8);
+
+ /* set the alpha to 255 on the destination surf */
+ valphamask = VEC_ALPHA_MASK();
+
+ /* set a vector full of alpha and 255-alpha */
+ ((unsigned char *)&valpha)[0] = alpha;
+ valpha = vec_splat(valpha, 0);
+
+ while(height--) {
+ int width = info->d_width;
+#define ONE_PIXEL_BLEND(condition, widthvar) while ((condition)) { \
+ Uint32 s = *srcp; \
+ Uint32 d = *dstp; \
+ Uint32 s1 = s & 0xff00ff; \
+ Uint32 d1 = d & 0xff00ff; \
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) \
+ & 0xff00ff; \
+ s &= 0xff00; \
+ d &= 0xff00; \
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \
+ *dstp = d1 | d | 0xff000000; \
+ ++srcp; \
+ ++dstp; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned char vs = (vector unsigned char)vec_ld(0, srcp);
+ width -= extrawidth;
+ while (width) {
+ vector unsigned char voverflow;
+ vector unsigned char vd;
+
+ /* s = *srcp */
+ voverflow = (vector unsigned char)vec_ld(15, srcp);
+ vs = vec_perm(vs, voverflow, valigner);
+
+ /* d = *dstp */
+ vd = (vector unsigned char)vec_ld(0, dstp);
+
+ VEC_MULTIPLY_ALPHA(vs, vd, valpha, mergePermute, v1, v8);
+
+ /* set the alpha channel to full on */
+ vd = vec_or(vd, valphamask);
+
+ /* *dstp = res */
+ vec_st((vector unsigned int)vd, 0, dstp);
+
+ srcp += 4;
+ dstp += 4;
+ width -= 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+ }
+#undef ONE_PIXEL_BLEND
+
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+#if __MWERKS__
+#pragma altivec_model off
+#endif
+#endif /* SDL_ALTIVEC_BLITTERS */
+
+/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
+static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+ + (s & d & 0x00010101)) | 0xff000000;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* fast RGB888->(A)RGB888 blending with surface alpha */
+static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ if(alpha == 128) {
+ BlitRGBtoRGBSurfaceAlpha128(info);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ Uint32 s;
+ Uint32 d;
+ Uint32 s1;
+ Uint32 d1;
+
+ while(height--) {
+ DUFFS_LOOP_DOUBLE2({
+ /* One Pixel Blend */
+ s = *srcp;
+ d = *dstp;
+ s1 = s & 0xff00ff;
+ d1 = d & 0xff00ff;
+ d1 = (d1 + ((s1 - d1) * alpha >> 8))
+ & 0xff00ff;
+ s &= 0xff00;
+ d &= 0xff00;
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+ *dstp = d1 | d | 0xff000000;
+ ++srcp;
+ ++dstp;
+ },{
+ /* Two Pixels Blend */
+ s = *srcp;
+ d = *dstp;
+ s1 = s & 0xff00ff;
+ d1 = d & 0xff00ff;
+ d1 += (s1 - d1) * alpha >> 8;
+ d1 &= 0xff00ff;
+
+ s = ((s & 0xff00) >> 8) |
+ ((srcp[1] & 0xff00) << 8);
+ d = ((d & 0xff00) >> 8) |
+ ((dstp[1] & 0xff00) << 8);
+ d += (s - d) * alpha >> 8;
+ d &= 0x00ff00ff;
+
+ *dstp++ = d1 | ((d << 8) & 0xff00) | 0xff000000;
+ ++srcp;
+
+ s1 = *srcp;
+ d1 = *dstp;
+ s1 &= 0xff00ff;
+ d1 &= 0xff00ff;
+ d1 += (s1 - d1) * alpha >> 8;
+ d1 &= 0xff00ff;
+
+ *dstp = d1 | ((d >> 8) & 0xff00) | 0xff000000;
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 dalpha;
+ Uint32 d;
+ Uint32 s1;
+ Uint32 d1;
+ Uint32 s = *srcp;
+ Uint32 alpha = s >> 24;
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha) {
+ if(alpha == SDL_ALPHA_OPAQUE) {
+ *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
+ } else {
+ /*
+ * take out the middle component (green), and process
+ * the other two in parallel. One multiply less.
+ */
+ d = *dstp;
+ dalpha = d & 0xff000000;
+ s1 = s & 0xff00ff;
+ d1 = d & 0xff00ff;
+ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
+ s &= 0xff00;
+ d &= 0xff00;
+ d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+ *dstp = d1 | d | dalpha;
+ }
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+#if GCC_ASMBLIT
+/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat* sf = info->src;
+ Uint32 amask = sf->Amask;
+
+ __asm__ (
+ /* make mm6 all zeros. */
+ "pxor %%mm6, %%mm6\n"
+
+ /* Make a mask to preserve the alpha. */
+ "movd %0, %%mm7\n\t" /* 0000F000 -> mm7 */
+ "punpcklbw %%mm7, %%mm7\n\t" /* FF000000 -> mm7 */
+ "pcmpeqb %%mm4, %%mm4\n\t" /* FFFFFFFF -> mm4 */
+ "movq %%mm4, %%mm3\n\t" /* FFFFFFFF -> mm3 (for later) */
+ "pxor %%mm4, %%mm7\n\t" /* 00FFFFFF -> mm7 (mult mask) */
+
+ /* form channel masks */
+ "movq %%mm7, %%mm4\n\t" /* 00FFFFFF -> mm4 */
+ "packsswb %%mm6, %%mm4\n\t" /* 00000FFF -> mm4 (channel mask) */
+ "packsswb %%mm6, %%mm3\n\t" /* 0000FFFF -> mm3 */
+ "pxor %%mm4, %%mm3\n\t" /* 0000F000 -> mm3 (~channel mask) */
+
+ /* get alpha channel shift */
+ "movd %1, %%mm5\n\t" /* Ashift -> mm5 */
+
+ : /* nothing */ : "rm" (amask), "rm" ((Uint32) sf->Ashift) );
+
+ while(height--) {
+
+ DUFFS_LOOP4({
+ Uint32 alpha;
+
+ __asm__ (
+ "prefetch 64(%0)\n"
+ "prefetch 64(%1)\n"
+ : : "r" (srcp), "r" (dstp) );
+
+ alpha = *srcp & amask;
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha == 0) {
+ /* do nothing */
+ }
+ else if(alpha == amask) {
+ /* opaque alpha -- copy RGB, keep dst alpha */
+ /* using MMX here to free up regular registers for other things */
+ __asm__ (
+ "movd (%0), %%mm0\n\t" /* src(ARGB) -> mm0 (0000ARGB)*/
+ "movd (%1), %%mm1\n\t" /* dst(ARGB) -> mm1 (0000ARGB)*/
+ "pand %%mm4, %%mm0\n\t" /* src & chanmask -> mm0 */
+ "pand %%mm3, %%mm1\n\t" /* dst & ~chanmask -> mm2 */
+ "por %%mm0, %%mm1\n\t" /* src | dst -> mm1 */
+ "movd %%mm1, (%1) \n\t" /* mm1 -> dst */
+
+ : : "r" (srcp), "r" (dstp) );
+ }
+
+ else {
+ __asm__ (
+ /* load in the source, and dst. */
+ "movd (%0), %%mm0\n" /* mm0(s) = 0 0 0 0 | As Rs Gs Bs */
+ "movd (%1), %%mm1\n" /* mm1(d) = 0 0 0 0 | Ad Rd Gd Bd */
+
+ /* Move the src alpha into mm2 */
+
+ /* if supporting pshufw */
+ /*"pshufw $0x55, %%mm0, %%mm2\n" */ /* mm2 = 0 As 0 As | 0 As 0 As */
+ /*"psrlw $8, %%mm2\n" */
+
+ /* else: */
+ "movd %2, %%mm2\n"
+ "psrld %%mm5, %%mm2\n" /* mm2 = 0 0 0 0 | 0 0 0 As */
+ "punpcklwd %%mm2, %%mm2\n" /* mm2 = 0 0 0 0 | 0 As 0 As */
+ "punpckldq %%mm2, %%mm2\n" /* mm2 = 0 As 0 As | 0 As 0 As */
+ "pand %%mm7, %%mm2\n" /* to preserve dest alpha */
+
+ /* move the colors into words. */
+ "punpcklbw %%mm6, %%mm0\n" /* mm0 = 0 As 0 Rs | 0 Gs 0 Bs */
+ "punpcklbw %%mm6, %%mm1\n" /* mm0 = 0 Ad 0 Rd | 0 Gd 0 Bd */
+
+ /* src - dst */
+ "psubw %%mm1, %%mm0\n" /* mm0 = As-Ad Rs-Rd | Gs-Gd Bs-Bd */
+
+ /* A * (src-dst) */
+ "pmullw %%mm2, %%mm0\n" /* mm0 = 0*As-d As*Rs-d | As*Gs-d As*Bs-d */
+ "psrlw $8, %%mm0\n" /* mm0 = 0>>8 Rc>>8 | Gc>>8 Bc>>8 */
+ "paddb %%mm1, %%mm0\n" /* mm0 = 0+Ad Rc+Rd | Gc+Gd Bc+Bd */
+
+ "packuswb %%mm0, %%mm0\n" /* mm0 = | Ac Rc Gc Bc */
+
+ "movd %%mm0, (%1)\n" /* result in mm0 */
+
+ : : "r" (srcp), "r" (dstp), "r" (alpha) );
+
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+
+ __asm__ (
+ "emms\n"
+ : );
+}
+/* End GCC_ASMBLIT*/
+
+#elif MSVC_ASMBLIT
+/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */
+static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint32 *dstp = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip >> 2;
+ SDL_PixelFormat* sf = info->src;
+ Uint32 chanmask = sf->Rmask | sf->Gmask | sf->Bmask;
+ Uint32 amask = sf->Amask;
+ Uint32 ashift = sf->Ashift;
+ Uint64 multmask;
+
+ __m64 src1, dst1, mm_alpha, mm_zero, dmask;
+
+ mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */
+ multmask = ~(0xFFFFi64 << (ashift * 2));
+ dmask = *(__m64*) &multmask; /* dst alpha mask -> dmask */
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 alpha;
+
+ _m_prefetch(srcp + 16);
+ _m_prefetch(dstp + 16);
+
+ alpha = *srcp & amask;
+ if (alpha == 0) {
+ /* do nothing */
+ } else if (alpha == amask) {
+ /* copy RGB, keep dst alpha */
+ *dstp = (*srcp & chanmask) | (*dstp & ~chanmask);
+ } else {
+ src1 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src1 (0000ARGB)*/
+ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* 0A0R0G0B -> src1 */
+
+ dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB)*/
+ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */
+
+ mm_alpha = _mm_cvtsi32_si64(alpha); /* alpha -> mm_alpha (0000000A) */
+ mm_alpha = _mm_srli_si64(mm_alpha, ashift); /* mm_alpha >> ashift -> mm_alpha(0000000A) */
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ mm_alpha = _mm_and_si64(mm_alpha, dmask); /* 000A0A0A -> mm_alpha, preserve dst alpha on add */
+
+ /* blend */
+ src1 = _mm_sub_pi16(src1, dst1);/* src - dst -> src1 */
+ src1 = _mm_mullo_pi16(src1, mm_alpha); /* (src - dst) * alpha -> src1 */
+ src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1(000R0G0B) */
+ dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst) -> dst1(0A0R0G0B) */
+ dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */
+
+ *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */
+ }
+ ++srcp;
+ ++dstp;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+}
+/* End MSVC_ASMBLIT */
+
+#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */
+
+/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
+
+/* blend a single 16 bit pixel at 50% */
+#define BLEND16_50(d, s, mask) \
+ ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
+
+/* blend two 16 bit pixels at 50% */
+#define BLEND2x16_50(d, s, mask) \
+ (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
+ + (s & d & (~(mask | mask << 16))))
+
+static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+
+ while(height--) {
+ if(((uintptr_t)srcp ^ (uintptr_t)dstp) & 2) {
+ /*
+ * Source and destination not aligned, pipeline it.
+ * This is mostly a win for big blits but no loss for
+ * small ones
+ */
+ Uint32 prev_sw;
+ int w = width;
+
+ /* handle odd destination */
+ if((uintptr_t)dstp & 2) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ dstp++;
+ srcp++;
+ w--;
+ }
+ srcp++; /* srcp is now 32-bit aligned */
+
+ /* bootstrap pipeline with first halfword */
+ prev_sw = ((Uint32 *)srcp)[-1];
+
+ while(w > 1) {
+ Uint32 sw, dw, s;
+ sw = *(Uint32 *)srcp;
+ dw = *(Uint32 *)dstp;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ s = (prev_sw << 16) + (sw >> 16);
+#else
+ s = (prev_sw >> 16) + (sw << 16);
+#endif
+ prev_sw = sw;
+ *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask);
+ dstp += 2;
+ srcp += 2;
+ w -= 2;
+ }
+
+ /* final pixel if any */
+ if(w) {
+ Uint16 d = *dstp, s;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ s = (Uint16)prev_sw;
+#else
+ s = (Uint16)(prev_sw >> 16);
+#endif
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ }
+ srcp += srcskip - 1;
+ dstp += dstskip;
+ } else {
+ /* source and destination are aligned */
+ int w = width;
+
+ /* first odd pixel? */
+ if((uintptr_t)srcp & 2) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ w--;
+ }
+ /* srcp and dstp are now 32-bit aligned */
+
+ while(w > 1) {
+ Uint32 sw = *(Uint32 *)srcp;
+ Uint32 dw = *(Uint32 *)dstp;
+ *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask);
+ srcp += 2;
+ dstp += 2;
+ w -= 2;
+ }
+
+ /* last odd pixel? */
+ if(w) {
+ Uint16 d = *dstp, s = *srcp;
+ *dstp = BLEND16_50(d, s, mask);
+ srcp++;
+ dstp++;
+ }
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+#if GCC_ASMBLIT
+/* fast RGB565->RGB565 blending with surface alpha */
+static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xf7de);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ Uint32 s, d;
+ Uint64 load;
+
+ alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */
+ load = alpha;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ movq_m2r(load, mm0); /* alpha(0000000A) -> mm0 */
+ punpcklwd_r2r(mm0, mm0); /* 00000A0A -> mm0 */
+ punpcklwd_r2r(mm0, mm0); /* 0A0A0A0A -> mm0 */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ psllq_i2r(3, mm0);
+
+ /* Setup the 565 color channel masks */
+ load = 0x07E007E007E007E0ULL;
+ movq_m2r(load, mm4); /* MASKGREEN -> mm4 */
+ load = 0x001F001F001F001FULL;
+ movq_m2r(load, mm7); /* MASKBLUE -> mm7 */
+ while(height--) {
+ DUFFS_LOOP_QUATRO2(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = d | d >> 16;
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = d | d >> 16;
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = d | d >> 16;
+ },{
+ movq_m2r((*srcp), mm2);/* 4 src pixels -> mm2 */
+ movq_m2r((*dstp), mm3);/* 4 dst pixels -> mm3 */
+
+ /* red -- does not need a mask since the right shift clears
+ the uninteresting bits */
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 [000r 000r 000r 000r] */
+ psrlw_i2r(11, mm6); /* mm6 >> 11 -> mm6 [000r 000r 000r 000r] */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* alpha used is actually 11 bits
+ 11 + 5 = 16 bits, so the sign bits are lost */
+ psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+ psllw_i2r(11, mm6); /* mm6 << 11 -> mm6 */
+
+ movq_r2r(mm6, mm1); /* save new reds in dsts */
+
+ /* green -- process the bits in place */
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ pand_r2r(mm4, mm5); /* src & MASKGREEN -> mm5 */
+ pand_r2r(mm4, mm6); /* dst & MASKGREEN -> mm6 */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* 11 + 11 - 16 = 6 bits, so all the lower uninteresting
+ bits are gone and the sign bits present */
+ psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+
+ por_r2r(mm6, mm1); /* save new greens in dsts */
+
+ /* blue */
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ pand_r2r(mm7, mm5); /* src & MASKBLUE -> mm5[000b 000b 000b 000b] */
+ pand_r2r(mm7, mm6); /* dst & MASKBLUE -> mm6[000b 000b 000b 000b] */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* 11 + 5 = 16 bits, so the sign bits are lost and
+ the interesting bits will need to be MASKed */
+ psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+ pand_r2r(mm7, mm6); /* mm6 & MASKBLUE -> mm6[000b 000b 000b 000b] */
+
+ por_r2r(mm6, mm1); /* save new blues in dsts */
+
+ movq_r2m(mm1, *dstp); /* mm1 -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ emms();
+ }
+}
+
+/* fast RGB555->RGB555 blending with surface alpha */
+static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xfbde);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ Uint32 s, d;
+ Uint64 load;
+
+ alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */
+ load = alpha;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ movq_m2r(load, mm0); /* alpha(0000000A) -> mm0 */
+ punpcklwd_r2r(mm0, mm0); /* 00000A0A -> mm0 */
+ punpcklwd_r2r(mm0, mm0); /* 0A0A0A0A -> mm0 */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ psllq_i2r(3, mm0);
+
+ /* Setup the 555 color channel masks */
+ load = 0x03E003E003E003E0ULL;
+ movq_m2r(load, mm4); /* MASKGREEN -> mm4 */
+ load = 0x001F001F001F001FULL;
+ movq_m2r(load, mm7); /* MASKBLUE -> mm7 */
+ while(height--) {
+ DUFFS_LOOP_QUATRO2(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = d | d >> 16;
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = d | d >> 16;
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = d | d >> 16;
+ },{
+ movq_m2r((*srcp), mm2);/* 4 src pixels -> mm2 */
+ movq_m2r((*dstp), mm3);/* 4 dst pixels -> mm3 */
+
+ /* red -- process the bits in place */
+ psllq_i2r(5, mm4); /* turn MASKGREEN into MASKRED */
+ /* by reusing the GREEN mask we free up another mmx
+ register to accumulate the result */
+
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ pand_r2r(mm4, mm5); /* src & MASKRED -> mm5 */
+ pand_r2r(mm4, mm6); /* dst & MASKRED -> mm6 */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* 11 + 15 - 16 = 10 bits, uninteresting bits will be
+ cleared by a MASK below */
+ psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+ pand_r2r(mm4, mm6); /* mm6 & MASKRED -> mm6 */
+
+ psrlq_i2r(5, mm4); /* turn MASKRED back into MASKGREEN */
+
+ movq_r2r(mm6, mm1); /* save new reds in dsts */
+
+ /* green -- process the bits in place */
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ pand_r2r(mm4, mm5); /* src & MASKGREEN -> mm5 */
+ pand_r2r(mm4, mm6); /* dst & MASKGREEN -> mm6 */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmulhw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* 11 + 10 - 16 = 5 bits, so all the lower uninteresting
+ bits are gone and the sign bits present */
+ psllw_i2r(5, mm5); /* mm5 << 5 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+
+ por_r2r(mm6, mm1); /* save new greens in dsts */
+
+ /* blue */
+ movq_r2r(mm2, mm5); /* src -> mm5 */
+ movq_r2r(mm3, mm6); /* dst -> mm6 */
+ pand_r2r(mm7, mm5); /* src & MASKBLUE -> mm5[000b 000b 000b 000b] */
+ pand_r2r(mm7, mm6); /* dst & MASKBLUE -> mm6[000b 000b 000b 000b] */
+
+ /* blend */
+ psubw_r2r(mm6, mm5);/* src - dst -> mm5 */
+ pmullw_r2r(mm0, mm5); /* mm5 * alpha -> mm5 */
+ /* 11 + 5 = 16 bits, so the sign bits are lost and
+ the interesting bits will need to be MASKed */
+ psrlw_i2r(11, mm5); /* mm5 >> 11 -> mm5 */
+ paddw_r2r(mm5, mm6); /* mm5 + mm6(dst) -> mm6 */
+ pand_r2r(mm7, mm6); /* mm6 & MASKBLUE -> mm6[000b 000b 000b 000b] */
+
+ por_r2r(mm6, mm1); /* save new blues in dsts */
+
+ movq_r2m(mm1, *dstp);/* mm1 -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ emms();
+ }
+}
+/* End GCC_ASMBLIT */
+
+#elif MSVC_ASMBLIT
+/* fast RGB565->RGB565 blending with surface alpha */
+static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xf7de);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ Uint32 s, d;
+
+ __m64 src1, dst1, src2, dst2, gmask, bmask, mm_res, mm_alpha;
+
+ alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */
+ mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ mm_alpha = _mm_slli_si64(mm_alpha, 3);
+
+ /* Setup the 565 color channel masks */
+ gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */
+ bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */
+
+ while(height--) {
+ DUFFS_LOOP_QUATRO2(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */
+ dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */
+
+ /* red */
+ src2 = src1;
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 [000r 000r 000r 000r] */
+
+ dst2 = dst1;
+ dst2 = _mm_srli_pi16(dst2, 11); /* dst2 >> 11 -> dst2 [000r 000r 000r 000r] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_slli_pi16(dst2, 11); /* dst2 << 11 -> dst2 */
+
+ mm_res = dst2; /* RED -> mm_res */
+
+ /* green -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */
+
+ /* blue */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */
+
+ *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+
+/* fast RGB555->RGB555 blending with surface alpha */
+static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xfbde);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ Uint32 s, d;
+
+ __m64 src1, dst1, src2, dst2, rmask, gmask, bmask, mm_res, mm_alpha;
+
+ alpha &= ~(1+2+4); /* cut alpha to get the exact same behaviour */
+ mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */
+ mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */
+ /* position alpha to allow for mullo and mulhi on diff channels
+ to reduce the number of operations */
+ mm_alpha = _mm_slli_si64(mm_alpha, 3);
+
+ /* Setup the 555 color channel masks */
+ rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */
+ gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */
+ bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */
+
+ while(height--) {
+ DUFFS_LOOP_QUATRO2(
+ {
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ s = *srcp++;
+ d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ },{
+ src1 = *(__m64*)srcp; /* 4 src pixels -> src1 */
+ dst1 = *(__m64*)dstp; /* 4 dst pixels -> dst1 */
+
+ /* red -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, rmask); /* src & MASKRED -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, rmask); /* dst & MASKRED -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, rmask); /* dst2 & MASKRED -> dst2 */
+
+ mm_res = dst2; /* RED -> mm_res */
+
+ /* green -- process the bits in place */
+ src2 = src1;
+ src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */
+
+ dst2 = dst1;
+ dst2 = _mm_and_si64(dst2, gmask); /* dst & MASKGREEN -> dst2 */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mulhi_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_slli_pi16(src2, 5); /* src2 << 5 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN -> mm_res */
+
+ /* blue */
+ src2 = src1; /* src -> src2 */
+ src2 = _mm_and_si64(src2, bmask); /* src & MASKBLUE -> src2[000b 000b 000b 000b] */
+
+ dst2 = dst1; /* dst -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst & MASKBLUE -> dst2[000b 000b 000b 000b] */
+
+ /* blend */
+ src2 = _mm_sub_pi16(src2, dst2);/* src - dst -> src2 */
+ src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */
+ src2 = _mm_srli_pi16(src2, 11); /* src2 >> 11 -> src2 */
+ dst2 = _mm_add_pi16(src2, dst2); /* src2 + dst2 -> dst2 */
+ dst2 = _mm_and_si64(dst2, bmask); /* dst2 & MASKBLUE -> dst2 */
+
+ mm_res = _mm_or_si64(mm_res, dst2); /* RED | GREEN | BLUE -> mm_res */
+
+ *(__m64*)dstp = mm_res; /* mm_res -> 4 dst pixels */
+
+ srcp += 4;
+ dstp += 4;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ _mm_empty();
+ }
+}
+#endif /* GCC_ASMBLIT, MSVC_ASMBLIT */
+
+/* fast RGB565->RGB565 blending with surface alpha */
+static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha;
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xf7de);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x07e0f81f;
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast RGB555->RGB555 blending with surface alpha */
+static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info)
+{
+ unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */
+ if(alpha == 128) {
+ Blit16to16SurfaceAlpha128(info, 0xfbde);
+ } else {
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip >> 1;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+ alpha >>= 3; /* downscale alpha to 5 bits */
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 s = *srcp++;
+ Uint32 d = *dstp;
+ /*
+ * shift out the middle component (green) to
+ * the high 16 bits, and process all three RGB
+ * components at the same time.
+ */
+ s = (s | s << 16) & 0x03e07c1f;
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp++ = (Uint16)(d | d >> 16);
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+ }
+}
+
+/* fast ARGB8888->RGB565 blending with pixel alpha */
+static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+
+ while(height--) {
+ DUFFS_LOOP4({
+ Uint32 s = *srcp;
+ unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha) {
+ if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
+ *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
+ } else {
+ Uint32 d = *dstp;
+ /*
+ * convert source and destination to G0RAB65565
+ * and blend all components at the same time
+ */
+ s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
+ + (s >> 3 & 0x1f);
+ d = (d | d << 16) & 0x07e0f81f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x07e0f81f;
+ *dstp = (Uint16)(d | d >> 16);
+ }
+ }
+ srcp++;
+ dstp++;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* fast ARGB8888->RGB555 blending with pixel alpha */
+static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip >> 2;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip >> 1;
+
+ while(height--) {
+ DUFFS_LOOP4({
+ unsigned alpha;
+ Uint32 s = *srcp;
+ alpha = s >> 27; /* downscale alpha to 5 bits */
+ /* FIXME: Here we special-case opaque alpha since the
+ compositioning used (>>8 instead of /255) doesn't handle
+ it correctly. Also special-case alpha=0 for speed?
+ Benchmark this! */
+ if(alpha) {
+ if(alpha == (SDL_ALPHA_OPAQUE >> 3)) {
+ *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f));
+ } else {
+ Uint32 d = *dstp;
+ /*
+ * convert source and destination to G0RAB65565
+ * and blend all components at the same time
+ */
+ s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)
+ + (s >> 3 & 0x1f);
+ d = (d | d << 16) & 0x03e07c1f;
+ d += (s - d) * alpha >> 5;
+ d &= 0x03e07c1f;
+ *dstp = (Uint16)(d | d >> 16);
+ }
+ }
+ srcp++;
+ dstp++;
+ }, width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+/* General (slow) N->N blending with per-surface alpha */
+static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned sA = srcfmt->alpha;
+ unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+
+ if(sA) {
+ while ( height-- ) {
+ DUFFS_LOOP4(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ DISEMBLE_RGB(dst, dstbpp, dstfmt, Pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* General (slow) colorkeyed N->N blending with per-surface alpha */
+static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ Uint32 ckey = srcfmt->colorkey;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned sA = srcfmt->alpha;
+ unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+
+ while ( height-- ) {
+ DUFFS_LOOP4(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
+ if(sA && Pixel != ckey) {
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
+ DISEMBLE_RGB(dst, dstbpp, dstfmt, Pixel, dR, dG, dB);
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* General (slow) N->N blending with pixel alpha */
+static void BlitNtoNPixelAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+
+ int srcbpp;
+ int dstbpp;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ dstbpp = dstfmt->BytesPerPixel;
+
+ /* FIXME: for 8bpp source alpha, this doesn't get opaque values
+ quite right. for <8bpp source alpha, it gets them very wrong
+ (check all macros!)
+ It is unclear whether there is a good general solution that doesn't
+ need a branch (or a divide). */
+ while ( height-- ) {
+ DUFFS_LOOP4(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ unsigned sA;
+ unsigned dA;
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
+ if(sA) {
+ DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA);
+ ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ }
+ src += srcbpp;
+ dst += dstbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+
+SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index)
+{
+ SDL_PixelFormat *sf = surface->format;
+ SDL_PixelFormat *df = surface->map->dst->format;
+
+ if(sf->Amask == 0) {
+ if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
+ if(df->BytesPerPixel == 1)
+ return BlitNto1SurfaceAlphaKey;
+ else
+#if SDL_ALTIVEC_BLITTERS
+ if (sf->BytesPerPixel == 4 && df->BytesPerPixel == 4 &&
+ !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec())
+ return Blit32to32SurfaceAlphaKeyAltivec;
+ else
+#endif
+ return BlitNtoNSurfaceAlphaKey;
+ } else {
+ /* Per-surface alpha blits */
+ switch(df->BytesPerPixel) {
+ case 1:
+ return BlitNto1SurfaceAlpha;
+
+ case 2:
+ if(surface->map->identity) {
+ if(df->Gmask == 0x7e0)
+ {
+#if MMX_ASMBLIT
+ if(SDL_HasMMX())
+ return Blit565to565SurfaceAlphaMMX;
+ else
+#endif
+ return Blit565to565SurfaceAlpha;
+ }
+ else if(df->Gmask == 0x3e0)
+ {
+#if MMX_ASMBLIT
+ if(SDL_HasMMX())
+ return Blit555to555SurfaceAlphaMMX;
+ else
+#endif
+ return Blit555to555SurfaceAlpha;
+ }
+ }
+ return BlitNtoNSurfaceAlpha;
+
+ case 4:
+ if(sf->Rmask == df->Rmask
+ && sf->Gmask == df->Gmask
+ && sf->Bmask == df->Bmask
+ && sf->BytesPerPixel == 4)
+ {
+#if MMX_ASMBLIT
+ if(sf->Rshift % 8 == 0
+ && sf->Gshift % 8 == 0
+ && sf->Bshift % 8 == 0
+ && SDL_HasMMX())
+ return BlitRGBtoRGBSurfaceAlphaMMX;
+#endif
+ if((sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff)
+ {
+#if SDL_ALTIVEC_BLITTERS
+ if(!(surface->map->dst->flags & SDL_HWSURFACE)
+ && SDL_HasAltiVec())
+ return BlitRGBtoRGBSurfaceAlphaAltivec;
+#endif
+ return BlitRGBtoRGBSurfaceAlpha;
+ }
+ }
+#if SDL_ALTIVEC_BLITTERS
+ if((sf->BytesPerPixel == 4) &&
+ !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec())
+ return Blit32to32SurfaceAlphaAltivec;
+ else
+#endif
+ return BlitNtoNSurfaceAlpha;
+
+ case 3:
+ default:
+ return BlitNtoNSurfaceAlpha;
+ }
+ }
+ } else {
+ /* Per-pixel alpha blits */
+ switch(df->BytesPerPixel) {
+ case 1:
+ return BlitNto1PixelAlpha;
+
+ case 2:
+#if SDL_ALTIVEC_BLITTERS
+ if(sf->BytesPerPixel == 4 && !(surface->map->dst->flags & SDL_HWSURFACE) &&
+ df->Gmask == 0x7e0 &&
+ df->Bmask == 0x1f && SDL_HasAltiVec())
+ return Blit32to565PixelAlphaAltivec;
+ else
+#endif
+ if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000
+ && sf->Gmask == 0xff00
+ && ((sf->Rmask == 0xff && df->Rmask == 0x1f)
+ || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {
+ if(df->Gmask == 0x7e0)
+ return BlitARGBto565PixelAlpha;
+ else if(df->Gmask == 0x3e0)
+ return BlitARGBto555PixelAlpha;
+ }
+ return BlitNtoNPixelAlpha;
+
+ case 4:
+ if(sf->Rmask == df->Rmask
+ && sf->Gmask == df->Gmask
+ && sf->Bmask == df->Bmask
+ && sf->BytesPerPixel == 4)
+ {
+#if MMX_ASMBLIT
+ if(sf->Rshift % 8 == 0
+ && sf->Gshift % 8 == 0
+ && sf->Bshift % 8 == 0
+ && sf->Ashift % 8 == 0
+ && sf->Aloss == 0)
+ {
+ if(SDL_Has3DNow())
+ return BlitRGBtoRGBPixelAlphaMMX3DNOW;
+ if(SDL_HasMMX())
+ return BlitRGBtoRGBPixelAlphaMMX;
+ }
+#endif
+ if(sf->Amask == 0xff000000)
+ {
+#if SDL_ALTIVEC_BLITTERS
+ if(!(surface->map->dst->flags & SDL_HWSURFACE)
+ && SDL_HasAltiVec())
+ return BlitRGBtoRGBPixelAlphaAltivec;
+#endif
+ return BlitRGBtoRGBPixelAlpha;
+ }
+ }
+#if SDL_ALTIVEC_BLITTERS
+ if (sf->Amask && sf->BytesPerPixel == 4 &&
+ !(surface->map->dst->flags & SDL_HWSURFACE) && SDL_HasAltiVec())
+ return Blit32to32PixelAlphaAltivec;
+ else
+#endif
+ return BlitNtoNPixelAlpha;
+
+ case 3:
+ default:
+ return BlitNtoNPixelAlpha;
+ }
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_blit_N.c b/distrib/sdl-1.2.15/src/video/SDL_blit_N.c
new file mode 100644
index 0000000..858cee5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_blit_N.c
@@ -0,0 +1,2492 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_endian.h"
+#include "SDL_cpuinfo.h"
+#include "SDL_blit.h"
+
+/* Functions to blit from N-bit surfaces to other surfaces */
+
+#if SDL_ALTIVEC_BLITTERS
+#if __MWERKS__
+#pragma altivec_model on
+#endif
+#ifdef HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+#define assert(X)
+#ifdef __MACOSX__
+#include <sys/sysctl.h>
+static size_t GetL3CacheSize( void )
+{
+ const char key[] = "hw.l3cachesize";
+ u_int64_t result = 0;
+ size_t typeSize = sizeof( result );
+
+
+ int err = sysctlbyname( key, &result, &typeSize, NULL, 0 );
+ if( 0 != err ) return 0;
+
+ return result;
+}
+#else
+static size_t GetL3CacheSize( void )
+{
+ /* XXX: Just guess G4 */
+ return 2097152;
+}
+#endif /* __MACOSX__ */
+
+#if (defined(__MACOSX__) && (__GNUC__ < 4))
+ #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
+ #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) ( a,b,c,d,e,f,g,h )
+#else
+ #define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
+ (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
+ #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
+ (vector unsigned short) { a,b,c,d,e,f,g,h }
+#endif
+
+#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
+#define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
+ ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
+ 0x04+a, 0x04+b, 0x04+c, 0x04+d, \
+ 0x08+a, 0x08+b, 0x08+c, 0x08+d, \
+ 0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
+
+#define MAKE8888(dstfmt, r, g, b, a) \
+ ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
+ ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
+ ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
+ ((a<<dstfmt->Ashift)&dstfmt->Amask) )
+
+/*
+ * Data Stream Touch...Altivec cache prefetching.
+ *
+ * Don't use this on a G5...however, the speed boost is very significant
+ * on a G4.
+ */
+#define DST_CHAN_SRC 1
+#define DST_CHAN_DEST 2
+
+/* macro to set DST control word value... */
+#define DST_CTRL(size, count, stride) \
+ (((size) << 24) | ((count) << 16) | (stride))
+
+#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
+ ? vec_lvsl(0, src) \
+ : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
+
+/* Calculate the permute vector used for 32->32 swizzling */
+static vector unsigned char calc_swizzle32(const SDL_PixelFormat *srcfmt,
+ const SDL_PixelFormat *dstfmt)
+{
+ /*
+ * We have to assume that the bits that aren't used by other
+ * colors is alpha, and it's one complete byte, since some formats
+ * leave alpha with a zero mask, but we should still swizzle the bits.
+ */
+ /* ARGB */
+ const static struct SDL_PixelFormat default_pixel_format = {
+ NULL, 0, 0,
+ 0, 0, 0, 0,
+ 16, 8, 0, 24,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
+ 0, 0};
+ if (!srcfmt) {
+ srcfmt = &default_pixel_format;
+ }
+ if (!dstfmt) {
+ dstfmt = &default_pixel_format;
+ }
+ const vector unsigned char plus = VECUINT8_LITERAL(
+ 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x04, 0x04, 0x04,
+ 0x08, 0x08, 0x08, 0x08,
+ 0x0C, 0x0C, 0x0C, 0x0C );
+ vector unsigned char vswiz;
+ vector unsigned int srcvec;
+#define RESHIFT(X) (3 - ((X) >> 3))
+ Uint32 rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
+ Uint32 gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
+ Uint32 bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
+ Uint32 amask;
+ /* Use zero for alpha if either surface doesn't have alpha */
+ if (dstfmt->Amask) {
+ amask = ((srcfmt->Amask) ? RESHIFT(srcfmt->Ashift) : 0x10) << (dstfmt->Ashift);
+ } else {
+ amask = 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^ 0xFFFFFFFF);
+ }
+#undef RESHIFT
+ ((unsigned int *)(char*)&srcvec)[0] = (rmask | gmask | bmask | amask);
+ vswiz = vec_add(plus, (vector unsigned char)vec_splat(srcvec, 0));
+ return(vswiz);
+}
+
+static void Blit_RGB888_RGB565(SDL_BlitInfo *info);
+static void Blit_RGB888_RGB565Altivec(SDL_BlitInfo *info) {
+ int height = info->d_height;
+ Uint8 *src = (Uint8 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = (Uint8 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ vector unsigned char valpha = vec_splat_u8(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
+ vector unsigned char vgmerge = VECUINT8_LITERAL(
+ 0x00, 0x02, 0x00, 0x06,
+ 0x00, 0x0a, 0x00, 0x0e,
+ 0x00, 0x12, 0x00, 0x16,
+ 0x00, 0x1a, 0x00, 0x1e);
+ vector unsigned short v1 = vec_splat_u16(1);
+ vector unsigned short v3 = vec_splat_u16(3);
+ vector unsigned short v3f = VECUINT16_LITERAL(
+ 0x003f, 0x003f, 0x003f, 0x003f,
+ 0x003f, 0x003f, 0x003f, 0x003f);
+ vector unsigned short vfc = VECUINT16_LITERAL(
+ 0x00fc, 0x00fc, 0x00fc, 0x00fc,
+ 0x00fc, 0x00fc, 0x00fc, 0x00fc);
+ vector unsigned short vf800 = (vector unsigned short)vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->d_width;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, sA; \
+ DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
+ sR, sG, sB, sA); \
+ *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
+ ((sG << 3) & 0x000007E0) | \
+ ((sB >> 3) & 0x0000001F)); \
+ dst += 2; \
+ src += 4; \
+ widthvar--; \
+ }
+
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
+ vector unsigned int vsrc1, vsrc2;
+ vector unsigned char vdst;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+ vsrc1 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute);
+ src += 16;
+ vsrc = voverflow;
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+ vsrc2 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute);
+ /* 1555 */
+ vpixel = (vector unsigned short)vec_packpx(vsrc1, vsrc2);
+ vgpixel = (vector unsigned short)vec_perm(vsrc1, vsrc2, vgmerge);
+ vgpixel = vec_and(vgpixel, vfc);
+ vgpixel = vec_sl(vgpixel, v3);
+ vrpixel = vec_sl(vpixel, v1);
+ vrpixel = vec_and(vrpixel, vf800);
+ vbpixel = vec_and(vpixel, v3f);
+ vdst = vec_or((vector unsigned char)vrpixel, (vector unsigned char)vgpixel);
+ /* 565 */
+ vdst = vec_or(vdst, (vector unsigned char)vbpixel);
+ vec_st(vdst, 0, dst);
+
+ width -= 8;
+ src += 16;
+ dst += 16;
+ vsrc = voverflow;
+ }
+
+ assert(width == 0);
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+
+}
+
+static void Blit_RGB565_32Altivec(SDL_BlitInfo *info) {
+ int height = info->d_height;
+ Uint8 *src = (Uint8 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = (Uint8 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ unsigned alpha;
+ vector unsigned char valpha;
+ vector unsigned char vpermute;
+ vector unsigned short vf800;
+ vector unsigned int v8 = vec_splat_u32(8);
+ vector unsigned int v16 = vec_add(v8, v8);
+ vector unsigned short v2 = vec_splat_u16(2);
+ vector unsigned short v3 = vec_splat_u16(3);
+ /*
+ 0x10 - 0x1f is the alpha
+ 0x00 - 0x0e evens are the red
+ 0x01 - 0x0f odds are zero
+ */
+ vector unsigned char vredalpha1 = VECUINT8_LITERAL(
+ 0x10, 0x00, 0x01, 0x01,
+ 0x10, 0x02, 0x01, 0x01,
+ 0x10, 0x04, 0x01, 0x01,
+ 0x10, 0x06, 0x01, 0x01
+ );
+ vector unsigned char vredalpha2 = (vector unsigned char) (
+ vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16))
+ );
+ /*
+ 0x00 - 0x0f is ARxx ARxx ARxx ARxx
+ 0x11 - 0x0f odds are blue
+ */
+ vector unsigned char vblue1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x02, 0x11,
+ 0x04, 0x05, 0x06, 0x13,
+ 0x08, 0x09, 0x0a, 0x15,
+ 0x0c, 0x0d, 0x0e, 0x17
+ );
+ vector unsigned char vblue2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vblue1, v8)
+ );
+ /*
+ 0x00 - 0x0f is ARxB ARxB ARxB ARxB
+ 0x10 - 0x0e evens are green
+ */
+ vector unsigned char vgreen1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x10, 0x03,
+ 0x04, 0x05, 0x12, 0x07,
+ 0x08, 0x09, 0x14, 0x0b,
+ 0x0c, 0x0d, 0x16, 0x0f
+ );
+ vector unsigned char vgreen2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8))
+ );
+
+
+ assert(srcfmt->BytesPerPixel == 2);
+ assert(dstfmt->BytesPerPixel == 4);
+
+ vf800 = (vector unsigned short)vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ if (dstfmt->Amask && srcfmt->alpha) {
+ ((unsigned char *)&valpha)[0] = alpha = srcfmt->alpha;
+ valpha = vec_splat(valpha, 0);
+ } else {
+ alpha = 0;
+ valpha = vec_splat_u8(0);
+ }
+
+ vpermute = calc_swizzle32(NULL, dstfmt);
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->d_width;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ unsigned sR, sG, sB; \
+ unsigned short Pixel = *((unsigned short *)src); \
+ sR = (Pixel >> 8) & 0xf8; \
+ sG = (Pixel >> 3) & 0xfc; \
+ sB = (Pixel << 3) & 0xf8; \
+ ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
+ src += 2; \
+ dst += 4; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vR, vG, vB;
+ vector unsigned char vdst1, vdst2;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+
+ vR = vec_and((vector unsigned short)vsrc, vf800);
+ vB = vec_sl((vector unsigned short)vsrc, v3);
+ vG = vec_sl(vB, v2);
+
+ vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1);
+ vdst1 = vec_perm(vdst1, valpha, vpermute);
+ vec_st(vdst1, 0, dst);
+
+ vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2);
+ vdst2 = vec_perm(vdst2, valpha, vpermute);
+ vec_st(vdst2, 16, dst);
+
+ width -= 8;
+ dst += 32;
+ src += 16;
+ vsrc = voverflow;
+ }
+
+ assert(width == 0);
+
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+}
+
+
+static void Blit_RGB555_32Altivec(SDL_BlitInfo *info) {
+ int height = info->d_height;
+ Uint8 *src = (Uint8 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = (Uint8 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ unsigned alpha;
+ vector unsigned char valpha;
+ vector unsigned char vpermute;
+ vector unsigned short vf800;
+ vector unsigned int v8 = vec_splat_u32(8);
+ vector unsigned int v16 = vec_add(v8, v8);
+ vector unsigned short v1 = vec_splat_u16(1);
+ vector unsigned short v3 = vec_splat_u16(3);
+ /*
+ 0x10 - 0x1f is the alpha
+ 0x00 - 0x0e evens are the red
+ 0x01 - 0x0f odds are zero
+ */
+ vector unsigned char vredalpha1 = VECUINT8_LITERAL(
+ 0x10, 0x00, 0x01, 0x01,
+ 0x10, 0x02, 0x01, 0x01,
+ 0x10, 0x04, 0x01, 0x01,
+ 0x10, 0x06, 0x01, 0x01
+ );
+ vector unsigned char vredalpha2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16))
+ );
+ /*
+ 0x00 - 0x0f is ARxx ARxx ARxx ARxx
+ 0x11 - 0x0f odds are blue
+ */
+ vector unsigned char vblue1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x02, 0x11,
+ 0x04, 0x05, 0x06, 0x13,
+ 0x08, 0x09, 0x0a, 0x15,
+ 0x0c, 0x0d, 0x0e, 0x17
+ );
+ vector unsigned char vblue2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vblue1, v8)
+ );
+ /*
+ 0x00 - 0x0f is ARxB ARxB ARxB ARxB
+ 0x10 - 0x0e evens are green
+ */
+ vector unsigned char vgreen1 = VECUINT8_LITERAL(
+ 0x00, 0x01, 0x10, 0x03,
+ 0x04, 0x05, 0x12, 0x07,
+ 0x08, 0x09, 0x14, 0x0b,
+ 0x0c, 0x0d, 0x16, 0x0f
+ );
+ vector unsigned char vgreen2 = (vector unsigned char)(
+ vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8))
+ );
+
+
+ assert(srcfmt->BytesPerPixel == 2);
+ assert(dstfmt->BytesPerPixel == 4);
+
+ vf800 = (vector unsigned short)vec_splat_u8(-7);
+ vf800 = vec_sl(vf800, vec_splat_u16(8));
+
+ if (dstfmt->Amask && srcfmt->alpha) {
+ ((unsigned char *)&valpha)[0] = alpha = srcfmt->alpha;
+ valpha = vec_splat(valpha, 0);
+ } else {
+ alpha = 0;
+ valpha = vec_splat_u8(0);
+ }
+
+ vpermute = calc_swizzle32(NULL, dstfmt);
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned char voverflow;
+ vector unsigned char vsrc;
+
+ int width = info->d_width;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ while (condition) { \
+ unsigned sR, sG, sB; \
+ unsigned short Pixel = *((unsigned short *)src); \
+ sR = (Pixel >> 7) & 0xf8; \
+ sG = (Pixel >> 2) & 0xf8; \
+ sB = (Pixel << 3) & 0xf8; \
+ ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
+ src += 2; \
+ dst += 4; \
+ widthvar--; \
+ }
+ ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 8); /* trailing unaligned stores */
+ width -= extrawidth;
+ vsrc = vec_ld(0, src);
+ valigner = VEC_ALIGNER(src);
+
+ while (width) {
+ vector unsigned short vR, vG, vB;
+ vector unsigned char vdst1, vdst2;
+
+ voverflow = vec_ld(15, src);
+ vsrc = vec_perm(vsrc, voverflow, valigner);
+
+ vR = vec_and(vec_sl((vector unsigned short)vsrc,v1), vf800);
+ vB = vec_sl((vector unsigned short)vsrc, v3);
+ vG = vec_sl(vB, v3);
+
+ vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1);
+ vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1);
+ vdst1 = vec_perm(vdst1, valpha, vpermute);
+ vec_st(vdst1, 0, dst);
+
+ vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2);
+ vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2);
+ vdst2 = vec_perm(vdst2, valpha, vpermute);
+ vec_st(vdst2, 16, dst);
+
+ width -= 8;
+ dst += 32;
+ src += 16;
+ vsrc = voverflow;
+ }
+
+ assert(width == 0);
+
+
+ /* do scalar until we can align... */
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+
+ src += srcskip; /* move to next row, accounting for pitch. */
+ dst += dstskip;
+ }
+
+}
+
+static void BlitNtoNKey(SDL_BlitInfo *info);
+static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info);
+static void Blit32to32KeyAltivec(SDL_BlitInfo *info)
+{
+ int height = info->d_height;
+ Uint32 *srcp = (Uint32 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint32 *dstp = (Uint32 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int dstbpp = dstfmt->BytesPerPixel;
+ int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
+ unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0;
+ Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
+ Uint32 ckey = info->src->colorkey;
+ vector unsigned int valpha;
+ vector unsigned char vpermute;
+ vector unsigned char vzero;
+ vector unsigned int vckey;
+ vector unsigned int vrgbmask;
+ vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (info->d_width < 16) {
+ if(copy_alpha) {
+ BlitNtoNKeyCopyAlpha(info);
+ } else {
+ BlitNtoNKey(info);
+ }
+ return;
+ }
+ vzero = vec_splat_u8(0);
+ if (alpha) {
+ ((unsigned char *)&valpha)[0] = (unsigned char)alpha;
+ valpha = (vector unsigned int)vec_splat((vector unsigned char)valpha, 0);
+ } else {
+ valpha = (vector unsigned int)vzero;
+ }
+ ckey &= rgbmask;
+ ((unsigned int *)(char*)&vckey)[0] = ckey;
+ vckey = vec_splat(vckey, 0);
+ ((unsigned int *)(char*)&vrgbmask)[0] = rgbmask;
+ vrgbmask = vec_splat(vrgbmask, 0);
+
+ while (height--) {
+#define ONE_PIXEL_BLEND(condition, widthvar) \
+ if (copy_alpha) { \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB, sA; \
+ DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
+ sR, sG, sB, sA); \
+ if ( (Pixel & rgbmask) != ckey ) { \
+ ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
+ sR, sG, sB, sA); \
+ } \
+ dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
+ srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
+ widthvar--; \
+ } \
+ } else { \
+ while (condition) { \
+ Uint32 Pixel; \
+ unsigned sR, sG, sB; \
+ RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
+ if ( Pixel != ckey ) { \
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
+ ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
+ sR, sG, sB, alpha); \
+ } \
+ dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
+ srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
+ widthvar--; \
+ } \
+ }
+ int width = info->d_width;
+ ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
+ assert(width > 0);
+ if (width > 0) {
+ int extrawidth = (width % 4);
+ vector unsigned char valigner = VEC_ALIGNER(srcp);
+ vector unsigned int vs = vec_ld(0, srcp);
+ width -= extrawidth;
+ assert(width >= 4);
+ while (width) {
+ vector unsigned char vsel;
+ vector unsigned int vd;
+ vector unsigned int voverflow = vec_ld(15, srcp);
+ /* load the source vec */
+ vs = vec_perm(vs, voverflow, valigner);
+ /* vsel is set for items that match the key */
+ vsel = (vector unsigned char)vec_and(vs, vrgbmask);
+ vsel = (vector unsigned char)vec_cmpeq(vs, vckey);
+ /* permute the src vec to the dest format */
+ vs = vec_perm(vs, valpha, vpermute);
+ /* load the destination vec */
+ vd = vec_ld(0, dstp);
+ /* select the source and dest into vs */
+ vd = (vector unsigned int)vec_sel((vector unsigned char)vs, (vector unsigned char)vd, vsel);
+
+ vec_st(vd, 0, dstp);
+ srcp += 4;
+ width -= 4;
+ dstp += 4;
+ vs = voverflow;
+ }
+ ONE_PIXEL_BLEND((extrawidth), extrawidth);
+#undef ONE_PIXEL_BLEND
+ srcp += srcskip >> 2;
+ dstp += dstskip >> 2;
+ }
+ }
+}
+
+/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
+/* Use this on a G5 */
+static void ConvertAltivec32to32_noprefetch(SDL_BlitInfo *info)
+{
+ int height = info->d_height;
+ Uint32 *src = (Uint32 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint32 *dst = (Uint32 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ vector unsigned int vzero = vec_splat_u32(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (dstfmt->Amask && !srcfmt->Amask) {
+ if (srcfmt->alpha) {
+ vector unsigned char valpha;
+ ((unsigned char *)&valpha)[0] = srcfmt->alpha;
+ vzero = (vector unsigned int)vec_splat(valpha, 0);
+ }
+ }
+
+ assert(srcfmt->BytesPerPixel == 4);
+ assert(dstfmt->BytesPerPixel == 4);
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned int vbits;
+ vector unsigned int voverflow;
+ Uint32 bits;
+ Uint8 r, g, b, a;
+
+ int width = info->d_width;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+ while ((UNALIGNED_PTR(dst)) && (width)) {
+ bits = *(src++);
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ width--;
+ }
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 4);
+ width -= extrawidth;
+ valigner = VEC_ALIGNER(src);
+ vbits = vec_ld(0, src);
+
+ while (width) {
+ voverflow = vec_ld(15, src);
+ src += 4;
+ width -= 4;
+ vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
+ vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
+ vec_st(vbits, 0, dst); /* store it back out. */
+ dst += 4;
+ vbits = voverflow;
+ }
+
+ assert(width == 0);
+
+ /* cover pixels at the end of the row that didn't fit in 16 bytes. */
+ while (extrawidth) {
+ bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ extrawidth--;
+ }
+
+ src += srcskip >> 2; /* move to next row, accounting for pitch. */
+ dst += dstskip >> 2;
+ }
+
+}
+
+/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
+/* Use this on a G4 */
+static void ConvertAltivec32to32_prefetch(SDL_BlitInfo *info)
+{
+ const int scalar_dst_lead = sizeof (Uint32) * 4;
+ const int vector_dst_lead = sizeof (Uint32) * 16;
+
+ int height = info->d_height;
+ Uint32 *src = (Uint32 *) info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint32 *dst = (Uint32 *) info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ vector unsigned int vzero = vec_splat_u32(0);
+ vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
+ if (dstfmt->Amask && !srcfmt->Amask) {
+ if (srcfmt->alpha) {
+ vector unsigned char valpha;
+ ((unsigned char *)&valpha)[0] = srcfmt->alpha;
+ vzero = (vector unsigned int)vec_splat(valpha, 0);
+ }
+ }
+
+ assert(srcfmt->BytesPerPixel == 4);
+ assert(dstfmt->BytesPerPixel == 4);
+
+ while (height--) {
+ vector unsigned char valigner;
+ vector unsigned int vbits;
+ vector unsigned int voverflow;
+ Uint32 bits;
+ Uint8 r, g, b, a;
+
+ int width = info->d_width;
+ int extrawidth;
+
+ /* do scalar until we can align... */
+ while ((UNALIGNED_PTR(dst)) && (width)) {
+ vec_dstt(src+scalar_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_SRC);
+ vec_dstst(dst+scalar_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_DEST);
+ bits = *(src++);
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ width--;
+ }
+
+ /* After all that work, here's the vector part! */
+ extrawidth = (width % 4);
+ width -= extrawidth;
+ valigner = VEC_ALIGNER(src);
+ vbits = vec_ld(0, src);
+
+ while (width) {
+ vec_dstt(src+vector_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_SRC);
+ vec_dstst(dst+vector_dst_lead, DST_CTRL(2,32,1024), DST_CHAN_DEST);
+ voverflow = vec_ld(15, src);
+ src += 4;
+ width -= 4;
+ vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */
+ vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */
+ vec_st(vbits, 0, dst); /* store it back out. */
+ dst += 4;
+ vbits = voverflow;
+ }
+
+ assert(width == 0);
+
+ /* cover pixels at the end of the row that didn't fit in 16 bytes. */
+ while (extrawidth) {
+ bits = *(src++); /* max 7 pixels, don't bother with prefetch. */
+ RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
+ *(dst++) = MAKE8888(dstfmt, r, g, b, a);
+ extrawidth--;
+ }
+
+ src += srcskip >> 2; /* move to next row, accounting for pitch. */
+ dst += dstskip >> 2;
+ }
+
+ vec_dss(DST_CHAN_SRC);
+ vec_dss(DST_CHAN_DEST);
+}
+
+static Uint32 GetBlitFeatures( void )
+{
+ static Uint32 features = 0xffffffff;
+ if (features == 0xffffffff) {
+ /* Provide an override for testing .. */
+ char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
+ if (override) {
+ features = 0;
+ SDL_sscanf(override, "%u", &features);
+ } else {
+ features = ( 0
+ /* Feature 1 is has-MMX */
+ | ((SDL_HasMMX()) ? 1 : 0)
+ /* Feature 2 is has-AltiVec */
+ | ((SDL_HasAltiVec()) ? 2 : 0)
+ /* Feature 4 is dont-use-prefetch */
+ /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
+ | ((GetL3CacheSize() == 0) ? 4 : 0)
+ );
+ }
+ }
+ return features;
+}
+#if __MWERKS__
+#pragma altivec_model off
+#endif
+#else
+/* Feature 1 is has-MMX */
+#define GetBlitFeatures() ((Uint32)(SDL_HasMMX() ? 1 : 0))
+#endif
+
+/* This is now endian dependent */
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define HI 1
+#define LO 0
+#else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
+#define HI 0
+#define LO 1
+#endif
+
+#if SDL_HERMES_BLITTERS
+
+/* Heheheh, we coerce Hermes into using SDL blit information */
+#define X86_ASSEMBLER
+#define HermesConverterInterface SDL_BlitInfo
+#define HermesClearInterface void
+#define STACKCALL
+
+#include "../hermes/HeadMMX.h"
+#include "../hermes/HeadX86.h"
+
+#else
+
+/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
+#define RGB888_RGB332(dst, src) { \
+ dst = (Uint8)((((src)&0x00E00000)>>16)| \
+ (((src)&0x0000E000)>>11)| \
+ (((src)&0x000000C0)>>6)); \
+}
+static void Blit_RGB888_index8(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = (Uint32 *)info->s_pixels;
+ srcskip = info->s_skip/4;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+
+ if ( map == NULL ) {
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ RGB888_RGB332(*dst++, *src);
+ , width);
+#else
+ for ( c=width/4; c; --c ) {
+ /* Pack RGB into 8bit pixel */
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ }
+ switch ( width & 3 ) {
+ case 3:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ case 2:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ case 1:
+ RGB888_RGB332(*dst++, *src);
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ int Pixel;
+
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ , width);
+#else
+ for ( c=width/4; c; --c ) {
+ /* Pack RGB into 8bit pixel */
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+ switch ( width & 3 ) {
+ case 3:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 2:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 1:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
+#define RGB888_RGB555(dst, src) { \
+ *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
+ (((*src)&0x0000F800)>>6)| \
+ (((*src)&0x000000F8)>>3)); \
+}
+#define RGB888_RGB555_TWO(dst, src) { \
+ *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
+ (((src[HI])&0x0000F800)>>6)| \
+ (((src[HI])&0x000000F8)>>3))<<16)| \
+ (((src[LO])&0x00F80000)>>9)| \
+ (((src[LO])&0x0000F800)>>6)| \
+ (((src[LO])&0x000000F8)>>3); \
+}
+static void Blit_RGB888_RGB555(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ Uint16 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = (Uint32 *)info->s_pixels;
+ srcskip = info->s_skip/4;
+ dst = (Uint16 *)info->d_pixels;
+ dstskip = info->d_skip/2;
+
+#ifdef USE_DUFFS_LOOP
+ while ( height-- ) {
+ DUFFS_LOOP(
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ , width);
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ( (long)dst & 0x03 ) {
+ /* Don't do anything if width is 0 */
+ if ( width == 0 ) {
+ return;
+ }
+ --width;
+
+ while ( height-- ) {
+ /* Perform copy alignment */
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB555_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB555(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
+#define RGB888_RGB565(dst, src) { \
+ *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
+ (((*src)&0x0000FC00)>>5)| \
+ (((*src)&0x000000F8)>>3)); \
+}
+#define RGB888_RGB565_TWO(dst, src) { \
+ *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
+ (((src[HI])&0x0000FC00)>>5)| \
+ (((src[HI])&0x000000F8)>>3))<<16)| \
+ (((src[LO])&0x00F80000)>>8)| \
+ (((src[LO])&0x0000FC00)>>5)| \
+ (((src[LO])&0x000000F8)>>3); \
+}
+static void Blit_RGB888_RGB565(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint32 *src;
+ Uint16 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = (Uint32 *)info->s_pixels;
+ srcskip = info->s_skip/4;
+ dst = (Uint16 *)info->d_pixels;
+ dstskip = info->d_skip/2;
+
+#ifdef USE_DUFFS_LOOP
+ while ( height-- ) {
+ DUFFS_LOOP(
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ , width);
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ /* Memory align at 4-byte boundary, if necessary */
+ if ( (long)dst & 0x03 ) {
+ /* Don't do anything if width is 0 */
+ if ( width == 0 ) {
+ return;
+ }
+ --width;
+
+ while ( height-- ) {
+ /* Perform copy alignment */
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ case 2:
+ RGB888_RGB565_TWO(dst, src);
+ src += 2;
+ dst += 2;
+ break;
+ case 1:
+ RGB888_RGB565(dst, src);
+ ++src;
+ ++dst;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+#endif /* SDL_HERMES_BLITTERS */
+
+
+/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
+#define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
+static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ Uint32 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = (Uint8 *)info->s_pixels;
+ srcskip = info->s_skip;
+ dst = (Uint32 *)info->d_pixels;
+ dstskip = info->d_skip/4;
+
+#ifdef USE_DUFFS_LOOP
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ while ( height-- ) {
+ /* Copy in 4 pixel chunks */
+ for ( c=width/4; c; --c ) {
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ }
+ /* Get any leftovers */
+ switch (width & 3) {
+ case 3:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ case 2:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ case 1:
+ *dst++ = RGB565_32(dst, src, map);
+ src += 2;
+ break;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+
+/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
+static const Uint32 RGB565_ARGB8888_LUT[512] = {
+ 0x00000000, 0xff000000, 0x00000008, 0xff002000,
+ 0x00000010, 0xff004000, 0x00000018, 0xff006100,
+ 0x00000020, 0xff008100, 0x00000029, 0xff00a100,
+ 0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
+ 0x00000041, 0xff080000, 0x0000004a, 0xff082000,
+ 0x00000052, 0xff084000, 0x0000005a, 0xff086100,
+ 0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
+ 0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
+ 0x00000083, 0xff100000, 0x0000008b, 0xff102000,
+ 0x00000094, 0xff104000, 0x0000009c, 0xff106100,
+ 0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
+ 0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
+ 0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
+ 0x000000d5, 0xff184000, 0x000000de, 0xff186100,
+ 0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
+ 0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
+ 0x00000400, 0xff200000, 0x00000408, 0xff202000,
+ 0x00000410, 0xff204000, 0x00000418, 0xff206100,
+ 0x00000420, 0xff208100, 0x00000429, 0xff20a100,
+ 0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
+ 0x00000441, 0xff290000, 0x0000044a, 0xff292000,
+ 0x00000452, 0xff294000, 0x0000045a, 0xff296100,
+ 0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
+ 0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
+ 0x00000483, 0xff310000, 0x0000048b, 0xff312000,
+ 0x00000494, 0xff314000, 0x0000049c, 0xff316100,
+ 0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
+ 0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
+ 0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
+ 0x000004d5, 0xff394000, 0x000004de, 0xff396100,
+ 0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
+ 0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
+ 0x00000800, 0xff410000, 0x00000808, 0xff412000,
+ 0x00000810, 0xff414000, 0x00000818, 0xff416100,
+ 0x00000820, 0xff418100, 0x00000829, 0xff41a100,
+ 0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
+ 0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
+ 0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
+ 0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
+ 0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
+ 0x00000883, 0xff520000, 0x0000088b, 0xff522000,
+ 0x00000894, 0xff524000, 0x0000089c, 0xff526100,
+ 0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
+ 0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
+ 0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
+ 0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
+ 0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
+ 0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
+ 0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
+ 0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
+ 0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
+ 0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
+ 0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
+ 0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
+ 0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
+ 0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
+ 0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
+ 0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
+ 0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
+ 0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
+ 0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
+ 0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
+ 0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
+ 0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
+ 0x00001000, 0xff830000, 0x00001008, 0xff832000,
+ 0x00001010, 0xff834000, 0x00001018, 0xff836100,
+ 0x00001020, 0xff838100, 0x00001029, 0xff83a100,
+ 0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
+ 0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
+ 0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
+ 0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
+ 0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
+ 0x00001083, 0xff940000, 0x0000108b, 0xff942000,
+ 0x00001094, 0xff944000, 0x0000109c, 0xff946100,
+ 0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
+ 0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
+ 0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
+ 0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
+ 0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
+ 0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
+ 0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
+ 0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
+ 0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
+ 0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
+ 0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
+ 0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
+ 0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
+ 0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
+ 0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
+ 0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
+ 0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
+ 0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
+ 0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
+ 0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
+ 0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
+ 0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
+ 0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
+ 0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
+ 0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
+ 0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
+ 0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
+ 0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
+ 0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
+ 0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
+ 0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
+ 0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
+ 0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
+ 0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
+ 0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
+ 0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
+ 0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
+ 0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
+ 0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
+ 0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
+ 0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
+ 0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
+ 0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
+ 0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
+ 0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
+ 0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
+ 0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
+ 0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
+ 0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
+ 0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
+ 0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
+ 0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
+ 0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
+ 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
+};
+static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info)
+{
+ Blit_RGB565_32(info, RGB565_ARGB8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
+static const Uint32 RGB565_ABGR8888_LUT[512] = {
+ 0xff000000, 0x00000000, 0xff080000, 0x00002000,
+ 0xff100000, 0x00004000, 0xff180000, 0x00006100,
+ 0xff200000, 0x00008100, 0xff290000, 0x0000a100,
+ 0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
+ 0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
+ 0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
+ 0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
+ 0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
+ 0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
+ 0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
+ 0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
+ 0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
+ 0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
+ 0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
+ 0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
+ 0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
+ 0xff000400, 0x00000020, 0xff080400, 0x00002020,
+ 0xff100400, 0x00004020, 0xff180400, 0x00006120,
+ 0xff200400, 0x00008120, 0xff290400, 0x0000a120,
+ 0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
+ 0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
+ 0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
+ 0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
+ 0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
+ 0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
+ 0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
+ 0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
+ 0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
+ 0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
+ 0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
+ 0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
+ 0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
+ 0xff000800, 0x00000041, 0xff080800, 0x00002041,
+ 0xff100800, 0x00004041, 0xff180800, 0x00006141,
+ 0xff200800, 0x00008141, 0xff290800, 0x0000a141,
+ 0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
+ 0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
+ 0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
+ 0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
+ 0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
+ 0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
+ 0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
+ 0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
+ 0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
+ 0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
+ 0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
+ 0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
+ 0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
+ 0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
+ 0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
+ 0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
+ 0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
+ 0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
+ 0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
+ 0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
+ 0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
+ 0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
+ 0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
+ 0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
+ 0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
+ 0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
+ 0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
+ 0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
+ 0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
+ 0xff001000, 0x00000083, 0xff081000, 0x00002083,
+ 0xff101000, 0x00004083, 0xff181000, 0x00006183,
+ 0xff201000, 0x00008183, 0xff291000, 0x0000a183,
+ 0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
+ 0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
+ 0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
+ 0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
+ 0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
+ 0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
+ 0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
+ 0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
+ 0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
+ 0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
+ 0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
+ 0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
+ 0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
+ 0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
+ 0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
+ 0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
+ 0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
+ 0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
+ 0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
+ 0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
+ 0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
+ 0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
+ 0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
+ 0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
+ 0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
+ 0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
+ 0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
+ 0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
+ 0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
+ 0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
+ 0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
+ 0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
+ 0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
+ 0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
+ 0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
+ 0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
+ 0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
+ 0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
+ 0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
+ 0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
+ 0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
+ 0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
+ 0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
+ 0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
+ 0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
+ 0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
+ 0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
+ 0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
+ 0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
+ 0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
+ 0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
+ 0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
+ 0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
+ 0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
+ 0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
+ 0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
+ 0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
+ 0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
+ 0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
+ 0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
+ 0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
+};
+static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info)
+{
+ Blit_RGB565_32(info, RGB565_ABGR8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
+static const Uint32 RGB565_RGBA8888_LUT[512] = {
+ 0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
+ 0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
+ 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
+ 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
+ 0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
+ 0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
+ 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
+ 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
+ 0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
+ 0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
+ 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
+ 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
+ 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
+ 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
+ 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
+ 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
+ 0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
+ 0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
+ 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
+ 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
+ 0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
+ 0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
+ 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
+ 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
+ 0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
+ 0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
+ 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
+ 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
+ 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
+ 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
+ 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
+ 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
+ 0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
+ 0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
+ 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
+ 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
+ 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
+ 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
+ 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
+ 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
+ 0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
+ 0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
+ 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
+ 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
+ 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
+ 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
+ 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
+ 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
+ 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
+ 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
+ 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
+ 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
+ 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
+ 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
+ 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
+ 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
+ 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
+ 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
+ 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
+ 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
+ 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
+ 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
+ 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
+ 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
+ 0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
+ 0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
+ 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
+ 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
+ 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
+ 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
+ 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
+ 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
+ 0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
+ 0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
+ 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
+ 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
+ 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
+ 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
+ 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
+ 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
+ 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
+ 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
+ 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
+ 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
+ 0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
+ 0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
+ 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
+ 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
+ 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
+ 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
+ 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
+ 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
+ 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
+ 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
+ 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
+ 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
+ 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
+ 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
+ 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
+ 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
+ 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
+ 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
+ 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
+ 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
+ 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
+ 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
+ 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
+ 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
+ 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
+ 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
+ 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
+ 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
+ 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
+ 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
+ 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
+ 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
+ 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
+ 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
+ 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
+ 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
+ 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
+ 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
+ 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
+ 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
+ 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
+ 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
+ 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
+ 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
+};
+static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info)
+{
+ Blit_RGB565_32(info, RGB565_RGBA8888_LUT);
+}
+
+/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
+static const Uint32 RGB565_BGRA8888_LUT[512] = {
+ 0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
+ 0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
+ 0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
+ 0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
+ 0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
+ 0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
+ 0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
+ 0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
+ 0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
+ 0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
+ 0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
+ 0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
+ 0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
+ 0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
+ 0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
+ 0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
+ 0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
+ 0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
+ 0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
+ 0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
+ 0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
+ 0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
+ 0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
+ 0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
+ 0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
+ 0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
+ 0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
+ 0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
+ 0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
+ 0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
+ 0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
+ 0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
+ 0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
+ 0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
+ 0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
+ 0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
+ 0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
+ 0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
+ 0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
+ 0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
+ 0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
+ 0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
+ 0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
+ 0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
+ 0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
+ 0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
+ 0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
+ 0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
+ 0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
+ 0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
+ 0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
+ 0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
+ 0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
+ 0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
+ 0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
+ 0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
+ 0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
+ 0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
+ 0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
+ 0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
+ 0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
+ 0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
+ 0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
+ 0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
+ 0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
+ 0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
+ 0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
+ 0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
+ 0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
+ 0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
+ 0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
+ 0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
+ 0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
+ 0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
+ 0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
+ 0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
+ 0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
+ 0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
+ 0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
+ 0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
+ 0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
+ 0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
+ 0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
+ 0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
+ 0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
+ 0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
+ 0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
+ 0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
+ 0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
+ 0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
+ 0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
+ 0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
+ 0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
+ 0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
+ 0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
+ 0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
+ 0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
+ 0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
+ 0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
+ 0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
+ 0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
+ 0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
+ 0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
+ 0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
+ 0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
+ 0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
+ 0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
+ 0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
+ 0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
+ 0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
+ 0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
+ 0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
+ 0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
+ 0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
+ 0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
+ 0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
+ 0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
+ 0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
+ 0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
+ 0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
+ 0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
+ 0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
+ 0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
+ 0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
+ 0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
+ 0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
+ 0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
+ 0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
+};
+static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info)
+{
+ Blit_RGB565_32(info, RGB565_BGRA8888_LUT);
+}
+
+/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
+#ifndef RGB888_RGB332
+#define RGB888_RGB332(dst, src) { \
+ dst = (((src)&0x00E00000)>>16)| \
+ (((src)&0x0000E000)>>11)| \
+ (((src)&0x000000C0)>>6); \
+}
+#endif
+static void Blit_RGB888_index8_map(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int Pixel;
+ int width, height;
+ Uint32 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = (Uint32 *)info->s_pixels;
+ srcskip = info->s_skip/4;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+
+#ifdef USE_DUFFS_LOOP
+ while ( height-- ) {
+ DUFFS_LOOP(
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ , width);
+ src += srcskip;
+ dst += dstskip;
+ }
+#else
+ while ( height-- ) {
+ for ( c=width/4; c; --c ) {
+ /* Pack RGB into 8bit pixel */
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+ switch ( width & 3 ) {
+ case 3:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 2:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ case 1:
+ RGB888_RGB332(Pixel, *src);
+ *dst++ = map[Pixel];
+ ++src;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+#endif /* USE_DUFFS_LOOP */
+}
+static void BlitNto1(SDL_BlitInfo *info)
+{
+#ifndef USE_DUFFS_LOOP
+ int c;
+#endif
+ int width, height;
+ Uint8 *src;
+ const Uint8 *map;
+ Uint8 *dst;
+ int srcskip, dstskip;
+ int srcbpp;
+ Uint32 Pixel;
+ int sR, sG, sB;
+ SDL_PixelFormat *srcfmt;
+
+ /* Set up some basic variables */
+ width = info->d_width;
+ height = info->d_height;
+ src = info->s_pixels;
+ srcskip = info->s_skip;
+ dst = info->d_pixels;
+ dstskip = info->d_skip;
+ map = info->table;
+ srcfmt = info->src;
+ srcbpp = srcfmt->BytesPerPixel;
+
+ if ( map == NULL ) {
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = ((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ;
+ }
+ dst++;
+ src += srcbpp;
+ , width);
+#else
+ for ( c=width; c; --c ) {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = ((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ;
+ }
+ dst++;
+ src += srcbpp;
+ }
+#endif
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+#ifdef USE_DUFFS_LOOP
+ DUFFS_LOOP(
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = map[((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ , width);
+#else
+ for ( c=width; c; --c ) {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( 1 ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = map[((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ }
+#endif /* USE_DUFFS_LOOP */
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
+static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint32 *src = (Uint32 *)info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint32 *dst = (Uint32 *)info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+
+ if (dstfmt->Amask) {
+ /* RGB->RGBA, SET_ALPHA */
+ Uint32 mask = (srcfmt->alpha >> dstfmt->Aloss) << dstfmt->Ashift;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ *dst = *src | mask;
+ ++dst;
+ ++src;
+ },
+ width);
+ src = (Uint32*)((Uint8*)src + srcskip);
+ dst = (Uint32*)((Uint8*)dst + dstskip);
+ }
+ } else {
+ /* RGBA->RGB, NO_ALPHA */
+ Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ *dst = *src & mask;
+ ++dst;
+ ++src;
+ },
+ width);
+ src = (Uint32*)((Uint8*)src + srcskip);
+ dst = (Uint32*)((Uint8*)dst + dstskip);
+ }
+ }
+}
+
+static void BlitNtoN(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitNtoNCopyAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ int srcbpp = srcfmt->BytesPerPixel;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int dstbpp = dstfmt->BytesPerPixel;
+ int c;
+
+ /* FIXME: should map alpha to [0..255] correctly! */
+ while ( height-- ) {
+ for ( c=width; c; --c ) {
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB, sA);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
+ sR, sG, sB, sA);
+ dst += dstbpp;
+ src += srcbpp;
+ }
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitNto1Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ const Uint8 *palmap = info->table;
+ Uint32 ckey = srcfmt->colorkey;
+ Uint32 rgbmask = ~srcfmt->Amask;
+ int srcbpp;
+ Uint32 Pixel;
+ unsigned sR, sG, sB;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ ckey &= rgbmask;
+
+ if ( palmap == NULL ) {
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( (Pixel & rgbmask) != ckey ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = (Uint8)(((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)));
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+ } else {
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB);
+ if ( (Pixel & rgbmask) != ckey ) {
+ /* Pack RGB into 8bit pixel */
+ *dst = (Uint8)palmap[((sR>>5)<<(3+2))|
+ ((sG>>5)<<(2)) |
+ ((sB>>6)<<(0)) ];
+ }
+ dst++;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+ }
+}
+
+static void Blit2to2Key(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint16 *srcp = (Uint16 *)info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint16 *dstp = (Uint16 *)info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ Uint32 rgbmask = ~info->src->Amask;
+
+ /* Set up some basic variables */
+ srcskip /= 2;
+ dstskip /= 2;
+ ckey &= rgbmask;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ if ( (*srcp & rgbmask) != ckey ) {
+ *dstp = *srcp;
+ }
+ dstp++;
+ srcp++;
+ },
+ width);
+ srcp += srcskip;
+ dstp += dstskip;
+ }
+}
+
+static void BlitNtoNKey(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
+ unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0;
+ Uint32 rgbmask = ~srcfmt->Amask;
+
+ /* Set up some basic variables */
+ ckey &= rgbmask;
+
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ Uint32 Pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
+ if ( (Pixel & rgbmask) != ckey ) {
+ RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
+ sR, sG, sB, alpha);
+ }
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
+{
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ Uint32 ckey = info->src->colorkey;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ Uint32 rgbmask = ~srcfmt->Amask;
+
+ Uint8 srcbpp;
+ Uint8 dstbpp;
+ Uint32 Pixel;
+ unsigned sR, sG, sB, sA;
+
+ /* Set up some basic variables */
+ srcbpp = srcfmt->BytesPerPixel;
+ dstbpp = dstfmt->BytesPerPixel;
+ ckey &= rgbmask;
+
+ /* FIXME: should map alpha to [0..255] correctly! */
+ while ( height-- ) {
+ DUFFS_LOOP(
+ {
+ DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel,
+ sR, sG, sB, sA);
+ if ( (Pixel & rgbmask) != ckey ) {
+ ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
+ sR, sG, sB, sA);
+ }
+ dst += dstbpp;
+ src += srcbpp;
+ },
+ width);
+ src += srcskip;
+ dst += dstskip;
+ }
+}
+
+/* Normal N to N optimized blitters */
+struct blit_table {
+ Uint32 srcR, srcG, srcB;
+ int dstbpp;
+ Uint32 dstR, dstG, dstB;
+ Uint32 blit_features;
+ void *aux_data;
+ SDL_loblit blitfunc;
+ enum { NO_ALPHA=1, SET_ALPHA=2, COPY_ALPHA=4 } alpha;
+};
+static const struct blit_table normal_blit_1[] = {
+ /* Default for 8-bit RGB source, an invalid combination */
+ { 0,0,0, 0, 0,0,0, 0, NULL, NULL },
+};
+static const struct blit_table normal_blit_2[] = {
+#if SDL_HERMES_BLITTERS
+ { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800,
+ 0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA },
+ { 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F,
+ 0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA },
+ { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00,
+ 0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA },
+#elif SDL_ALTIVEC_BLITTERS
+ /* has-altivec */
+ { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000,
+ 2, NULL, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
+ { 0x00007C00,0x000003E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000,
+ 2, NULL, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
+#endif
+ { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF,
+ 0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA },
+ { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000,
+ 0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA },
+ { 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00,
+ 0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA },
+ { 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000,
+ 0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA },
+
+ /* Default for 16-bit RGB source, used if no other blitter matches */
+ { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
+};
+static const struct blit_table normal_blit_3[] = {
+ /* Default for 24-bit RGB source, never optimized */
+ { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
+};
+static const struct blit_table normal_blit_4[] = {
+#if SDL_HERMES_BLITTERS
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
+ 1, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
+ 0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
+ 1, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
+ 0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
+ 1, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
+ 0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
+ 1, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
+ 0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
+ 1, ConvertMMXpII32_24RGB888, ConvertMMX, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
+ 0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000,
+ 0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000,
+ 0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00,
+ 0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000,
+ 0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA },
+#else
+#if SDL_ALTIVEC_BLITTERS
+ /* has-altivec | dont-use-prefetch */
+ { 0x00000000,0x00000000,0x00000000, 4, 0x00000000,0x00000000,0x00000000,
+ 6, NULL, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
+ /* has-altivec */
+ { 0x00000000,0x00000000,0x00000000, 4, 0x00000000,0x00000000,0x00000000,
+ 2, NULL, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
+ /* has-altivec */
+ { 0x00000000,0x00000000,0x00000000, 2, 0x0000F800,0x000007E0,0x0000001F,
+ 2, NULL, Blit_RGB888_RGB565Altivec, NO_ALPHA },
+#endif
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
+ 0, NULL, Blit_RGB888_RGB565, NO_ALPHA },
+ { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
+ 0, NULL, Blit_RGB888_RGB555, NO_ALPHA },
+#endif
+ /* Default for 32-bit RGB source, used if no other blitter matches */
+ { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
+};
+static const struct blit_table *normal_blit[] = {
+ normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
+};
+
+/* Mask matches table, or table entry is zero */
+#define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
+
+SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index)
+{
+ struct private_swaccel *sdata;
+ SDL_PixelFormat *srcfmt;
+ SDL_PixelFormat *dstfmt;
+ const struct blit_table *table;
+ int which;
+ SDL_loblit blitfun;
+
+ /* Set up data for choosing the blit */
+ sdata = surface->map->sw_data;
+ srcfmt = surface->format;
+ dstfmt = surface->map->dst->format;
+
+ if ( blit_index & 2 ) {
+ /* alpha or alpha+colorkey */
+ return SDL_CalculateAlphaBlit(surface, blit_index);
+ }
+
+ /* We don't support destinations less than 8-bits */
+ if ( dstfmt->BitsPerPixel < 8 ) {
+ return(NULL);
+ }
+
+ if(blit_index == 1) {
+ /* colorkey blit: Here we don't have too many options, mostly
+ because RLE is the preferred fast way to deal with this.
+ If a particular case turns out to be useful we'll add it. */
+
+ if(srcfmt->BytesPerPixel == 2
+ && surface->map->identity)
+ return Blit2to2Key;
+ else if(dstfmt->BytesPerPixel == 1)
+ return BlitNto1Key;
+ else {
+#if SDL_ALTIVEC_BLITTERS
+ if((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4) && SDL_HasAltiVec()) {
+ return Blit32to32KeyAltivec;
+ } else
+#endif
+
+ if(srcfmt->Amask && dstfmt->Amask)
+ return BlitNtoNKeyCopyAlpha;
+ else
+ return BlitNtoNKey;
+ }
+ }
+
+ blitfun = NULL;
+ if ( dstfmt->BitsPerPixel == 8 ) {
+ /* We assume 8-bit destinations are palettized */
+ if ( (srcfmt->BytesPerPixel == 4) &&
+ (srcfmt->Rmask == 0x00FF0000) &&
+ (srcfmt->Gmask == 0x0000FF00) &&
+ (srcfmt->Bmask == 0x000000FF) ) {
+ if ( surface->map->table ) {
+ blitfun = Blit_RGB888_index8_map;
+ } else {
+#if SDL_HERMES_BLITTERS
+ sdata->aux_data = ConvertX86p32_8RGB332;
+ blitfun = ConvertX86;
+#else
+ blitfun = Blit_RGB888_index8;
+#endif
+ }
+ } else {
+ blitfun = BlitNto1;
+ }
+ } else {
+ /* Now the meat, choose the blitter we want */
+ int a_need = NO_ALPHA;
+ if(dstfmt->Amask)
+ a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
+ table = normal_blit[srcfmt->BytesPerPixel-1];
+ for ( which=0; table[which].dstbpp; ++which ) {
+ if ( MASKOK(srcfmt->Rmask, table[which].srcR) &&
+ MASKOK(srcfmt->Gmask, table[which].srcG) &&
+ MASKOK(srcfmt->Bmask, table[which].srcB) &&
+ MASKOK(dstfmt->Rmask, table[which].dstR) &&
+ MASKOK(dstfmt->Gmask, table[which].dstG) &&
+ MASKOK(dstfmt->Bmask, table[which].dstB) &&
+ dstfmt->BytesPerPixel == table[which].dstbpp &&
+ (a_need & table[which].alpha) == a_need &&
+ ((table[which].blit_features & GetBlitFeatures()) == table[which].blit_features) )
+ break;
+ }
+ sdata->aux_data = table[which].aux_data;
+ blitfun = table[which].blitfunc;
+
+ if(blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */
+ /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
+ if ( srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4 &&
+ srcfmt->Rmask == dstfmt->Rmask &&
+ srcfmt->Gmask == dstfmt->Gmask &&
+ srcfmt->Bmask == dstfmt->Bmask ) {
+ blitfun = Blit4to4MaskAlpha;
+ } else if ( a_need == COPY_ALPHA ) {
+ blitfun = BlitNtoNCopyAlpha;
+ }
+ }
+ }
+
+#ifdef DEBUG_ASM
+#if SDL_HERMES_BLITTERS
+ if ( blitfun == ConvertMMX )
+ fprintf(stderr, "Using mmx blit\n");
+ else
+ if ( blitfun == ConvertX86 )
+ fprintf(stderr, "Using asm blit\n");
+ else
+#endif
+ if ( (blitfun == BlitNtoN) || (blitfun == BlitNto1) )
+ fprintf(stderr, "Using C blit\n");
+ else
+ fprintf(stderr, "Using optimized C blit\n");
+#endif /* DEBUG_ASM */
+
+ return(blitfun);
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_bmp.c b/distrib/sdl-1.2.15/src/video/SDL_bmp.c
new file mode 100644
index 0000000..d56cfd8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_bmp.c
@@ -0,0 +1,549 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Code to load and save surfaces in Windows BMP format.
+
+ Why support BMP format? Well, it's a native format for Windows, and
+ most image processing programs can read and write it. It would be nice
+ to be able to have at least one image format that we can natively load
+ and save, and since PNG is so complex that it would bloat the library,
+ BMP is a good alternative.
+
+ This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp.
+*/
+
+#include "SDL_video.h"
+#include "SDL_endian.h"
+
+/* Compression encodings for BMP files */
+#ifndef BI_RGB
+#define BI_RGB 0
+#define BI_RLE8 1
+#define BI_RLE4 2
+#define BI_BITFIELDS 3
+#endif
+
+
+SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc)
+{
+ SDL_bool was_error;
+ long fp_offset = 0;
+ int bmpPitch;
+ int i, pad;
+ SDL_Surface *surface;
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ SDL_Palette *palette;
+ Uint8 *bits;
+ Uint8 *top, *end;
+ SDL_bool topDown;
+ int ExpandBMP;
+
+ /* The Win32 BMP file header (14 bytes) */
+ char magic[2];
+ Uint32 bfSize;
+ Uint16 bfReserved1;
+ Uint16 bfReserved2;
+ Uint32 bfOffBits;
+
+ /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
+ Uint32 biSize;
+ Sint32 biWidth;
+ Sint32 biHeight;
+ Uint16 biPlanes;
+ Uint16 biBitCount;
+ Uint32 biCompression;
+ Uint32 biSizeImage;
+ Sint32 biXPelsPerMeter;
+ Sint32 biYPelsPerMeter;
+ Uint32 biClrUsed;
+ Uint32 biClrImportant;
+
+ /* Make sure we are passed a valid data source */
+ surface = NULL;
+ was_error = SDL_FALSE;
+ if ( src == NULL ) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Read in the BMP file header */
+ fp_offset = SDL_RWtell(src);
+ SDL_ClearError();
+ if ( SDL_RWread(src, magic, 1, 2) != 2 ) {
+ SDL_Error(SDL_EFREAD);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ if ( SDL_strncmp(magic, "BM", 2) != 0 ) {
+ SDL_SetError("File is not a Windows BMP file");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ bfSize = SDL_ReadLE32(src);
+ bfReserved1 = SDL_ReadLE16(src);
+ bfReserved2 = SDL_ReadLE16(src);
+ bfOffBits = SDL_ReadLE32(src);
+
+ /* Read the Win32 BITMAPINFOHEADER */
+ biSize = SDL_ReadLE32(src);
+ if ( biSize == 12 ) {
+ biWidth = (Uint32)SDL_ReadLE16(src);
+ biHeight = (Uint32)SDL_ReadLE16(src);
+ biPlanes = SDL_ReadLE16(src);
+ biBitCount = SDL_ReadLE16(src);
+ biCompression = BI_RGB;
+ biSizeImage = 0;
+ biXPelsPerMeter = 0;
+ biYPelsPerMeter = 0;
+ biClrUsed = 0;
+ biClrImportant = 0;
+ } else {
+ biWidth = SDL_ReadLE32(src);
+ biHeight = SDL_ReadLE32(src);
+ biPlanes = SDL_ReadLE16(src);
+ biBitCount = SDL_ReadLE16(src);
+ biCompression = SDL_ReadLE32(src);
+ biSizeImage = SDL_ReadLE32(src);
+ biXPelsPerMeter = SDL_ReadLE32(src);
+ biYPelsPerMeter = SDL_ReadLE32(src);
+ biClrUsed = SDL_ReadLE32(src);
+ biClrImportant = SDL_ReadLE32(src);
+ }
+
+ /* stop some compiler warnings. */
+ (void) bfSize;
+ (void) bfReserved1;
+ (void) bfReserved2;
+ (void) biPlanes;
+ (void) biSizeImage;
+ (void) biXPelsPerMeter;
+ (void) biYPelsPerMeter;
+ (void) biClrImportant;
+
+ if (biHeight < 0) {
+ topDown = SDL_TRUE;
+ biHeight = -biHeight;
+ } else {
+ topDown = SDL_FALSE;
+ }
+
+ /* Check for read error */
+ if ( SDL_strcmp(SDL_GetError(), "") != 0 ) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
+ switch (biBitCount) {
+ case 1:
+ case 4:
+ ExpandBMP = biBitCount;
+ biBitCount = 8;
+ break;
+ default:
+ ExpandBMP = 0;
+ break;
+ }
+
+ /* We don't support any BMP compression right now */
+ Rmask = Gmask = Bmask = 0;
+ switch (biCompression) {
+ case BI_RGB:
+ /* If there are no masks, use the defaults */
+ if ( bfOffBits == (14+biSize) ) {
+ /* Default values for the BMP format */
+ switch (biBitCount) {
+ case 15:
+ case 16:
+ Rmask = 0x7C00;
+ Gmask = 0x03E0;
+ Bmask = 0x001F;
+ break;
+ case 24:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Rmask = 0x000000FF;
+ Gmask = 0x0000FF00;
+ Bmask = 0x00FF0000;
+ break;
+#endif
+ case 32:
+ Rmask = 0x00FF0000;
+ Gmask = 0x0000FF00;
+ Bmask = 0x000000FF;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ /* Fall through -- read the RGB masks */
+
+ case BI_BITFIELDS:
+ switch (biBitCount) {
+ case 15:
+ case 16:
+ case 32:
+ Rmask = SDL_ReadLE32(src);
+ Gmask = SDL_ReadLE32(src);
+ Bmask = SDL_ReadLE32(src);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ SDL_SetError("Compressed BMP files not supported");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Create a compatible surface, note that the colors are RGB ordered */
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0);
+ if ( surface == NULL ) {
+ was_error = SDL_TRUE;
+ goto done;
+ }
+
+ /* Load the palette, if any */
+ palette = (surface->format)->palette;
+ if ( palette ) {
+ if ( biClrUsed == 0 ) {
+ biClrUsed = 1 << biBitCount;
+ }
+ if ( biSize == 12 ) {
+ for ( i = 0; i < (int)biClrUsed; ++i ) {
+ SDL_RWread(src, &palette->colors[i].b, 1, 1);
+ SDL_RWread(src, &palette->colors[i].g, 1, 1);
+ SDL_RWread(src, &palette->colors[i].r, 1, 1);
+ palette->colors[i].unused = 0;
+ }
+ } else {
+ for ( i = 0; i < (int)biClrUsed; ++i ) {
+ SDL_RWread(src, &palette->colors[i].b, 1, 1);
+ SDL_RWread(src, &palette->colors[i].g, 1, 1);
+ SDL_RWread(src, &palette->colors[i].r, 1, 1);
+ SDL_RWread(src, &palette->colors[i].unused, 1, 1);
+ }
+ }
+ palette->ncolors = biClrUsed;
+ }
+
+ /* Read the surface pixels. Note that the bmp image is upside down */
+ if ( SDL_RWseek(src, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
+ SDL_Error(SDL_EFSEEK);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ top = (Uint8 *)surface->pixels;
+ end = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
+ switch (ExpandBMP) {
+ case 1:
+ bmpPitch = (biWidth + 7) >> 3;
+ pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
+ break;
+ case 4:
+ bmpPitch = (biWidth + 1) >> 1;
+ pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
+ break;
+ default:
+ pad = ((surface->pitch%4) ?
+ (4-(surface->pitch%4)) : 0);
+ break;
+ }
+ if ( topDown ) {
+ bits = top;
+ } else {
+ bits = end - surface->pitch;
+ }
+ while ( bits >= top && bits < end ) {
+ switch (ExpandBMP) {
+ case 1:
+ case 4: {
+ Uint8 pixel = 0;
+ int shift = (8-ExpandBMP);
+ for ( i=0; i<surface->w; ++i ) {
+ if ( i%(8/ExpandBMP) == 0 ) {
+ if ( !SDL_RWread(src, &pixel, 1, 1) ) {
+ SDL_SetError(
+ "Error reading from BMP");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ }
+ *(bits+i) = (pixel>>shift);
+ pixel <<= ExpandBMP;
+ } }
+ break;
+
+ default:
+ if ( SDL_RWread(src, bits, 1, surface->pitch)
+ != surface->pitch ) {
+ SDL_Error(SDL_EFREAD);
+ was_error = SDL_TRUE;
+ goto done;
+ }
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ /* Byte-swap the pixels if needed. Note that the 24bpp
+ case has already been taken care of above. */
+ switch(biBitCount) {
+ case 15:
+ case 16: {
+ Uint16 *pix = (Uint16 *)bits;
+ for(i = 0; i < surface->w; i++)
+ pix[i] = SDL_Swap16(pix[i]);
+ break;
+ }
+
+ case 32: {
+ Uint32 *pix = (Uint32 *)bits;
+ for(i = 0; i < surface->w; i++)
+ pix[i] = SDL_Swap32(pix[i]);
+ break;
+ }
+ }
+#endif
+ break;
+ }
+ /* Skip padding bytes, ugh */
+ if ( pad ) {
+ Uint8 padbyte;
+ for ( i=0; i<pad; ++i ) {
+ SDL_RWread(src, &padbyte, 1, 1);
+ }
+ }
+ if ( topDown ) {
+ bits += surface->pitch;
+ } else {
+ bits -= surface->pitch;
+ }
+ }
+done:
+ if ( was_error ) {
+ if ( src ) {
+ SDL_RWseek(src, fp_offset, RW_SEEK_SET);
+ }
+ if ( surface ) {
+ SDL_FreeSurface(surface);
+ }
+ surface = NULL;
+ }
+ if ( freesrc && src ) {
+ SDL_RWclose(src);
+ }
+ return(surface);
+}
+
+int SDL_SaveBMP_RW (SDL_Surface *saveme, SDL_RWops *dst, int freedst)
+{
+ long fp_offset;
+ int i, pad;
+ SDL_Surface *surface;
+ Uint8 *bits;
+
+ /* The Win32 BMP file header (14 bytes) */
+ char magic[2] = { 'B', 'M' };
+ Uint32 bfSize;
+ Uint16 bfReserved1;
+ Uint16 bfReserved2;
+ Uint32 bfOffBits;
+
+ /* The Win32 BITMAPINFOHEADER struct (40 bytes) */
+ Uint32 biSize;
+ Sint32 biWidth;
+ Sint32 biHeight;
+ Uint16 biPlanes;
+ Uint16 biBitCount;
+ Uint32 biCompression;
+ Uint32 biSizeImage;
+ Sint32 biXPelsPerMeter;
+ Sint32 biYPelsPerMeter;
+ Uint32 biClrUsed;
+ Uint32 biClrImportant;
+
+ /* Make sure we have somewhere to save */
+ surface = NULL;
+ if ( dst ) {
+ if ( saveme->format->palette ) {
+ if ( saveme->format->BitsPerPixel == 8 ) {
+ surface = saveme;
+ } else {
+ SDL_SetError("%d bpp BMP files not supported",
+ saveme->format->BitsPerPixel);
+ }
+ }
+ else if ( (saveme->format->BitsPerPixel == 24) &&
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ (saveme->format->Rmask == 0x00FF0000) &&
+ (saveme->format->Gmask == 0x0000FF00) &&
+ (saveme->format->Bmask == 0x000000FF)
+#else
+ (saveme->format->Rmask == 0x000000FF) &&
+ (saveme->format->Gmask == 0x0000FF00) &&
+ (saveme->format->Bmask == 0x00FF0000)
+#endif
+ ) {
+ surface = saveme;
+ } else {
+ SDL_Rect bounds;
+
+ /* Convert to 24 bits per pixel */
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ saveme->w, saveme->h, 24,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x00FF0000, 0x0000FF00, 0x000000FF,
+#else
+ 0x000000FF, 0x0000FF00, 0x00FF0000,
+#endif
+ 0);
+ if ( surface != NULL ) {
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = saveme->w;
+ bounds.h = saveme->h;
+ if ( SDL_LowerBlit(saveme, &bounds, surface,
+ &bounds) < 0 ) {
+ SDL_FreeSurface(surface);
+ SDL_SetError(
+ "Couldn't convert image to 24 bpp");
+ surface = NULL;
+ }
+ }
+ }
+ }
+
+ if ( surface && (SDL_LockSurface(surface) == 0) ) {
+ const int bw = surface->w*surface->format->BytesPerPixel;
+
+ /* Set the BMP file header values */
+ bfSize = 0; /* We'll write this when we're done */
+ bfReserved1 = 0;
+ bfReserved2 = 0;
+ bfOffBits = 0; /* We'll write this when we're done */
+
+ /* Write the BMP file header values */
+ fp_offset = SDL_RWtell(dst);
+ SDL_ClearError();
+ SDL_RWwrite(dst, magic, 2, 1);
+ SDL_WriteLE32(dst, bfSize);
+ SDL_WriteLE16(dst, bfReserved1);
+ SDL_WriteLE16(dst, bfReserved2);
+ SDL_WriteLE32(dst, bfOffBits);
+
+ /* Set the BMP info values */
+ biSize = 40;
+ biWidth = surface->w;
+ biHeight = surface->h;
+ biPlanes = 1;
+ biBitCount = surface->format->BitsPerPixel;
+ biCompression = BI_RGB;
+ biSizeImage = surface->h*surface->pitch;
+ biXPelsPerMeter = 0;
+ biYPelsPerMeter = 0;
+ if ( surface->format->palette ) {
+ biClrUsed = surface->format->palette->ncolors;
+ } else {
+ biClrUsed = 0;
+ }
+ biClrImportant = 0;
+
+ /* Write the BMP info values */
+ SDL_WriteLE32(dst, biSize);
+ SDL_WriteLE32(dst, biWidth);
+ SDL_WriteLE32(dst, biHeight);
+ SDL_WriteLE16(dst, biPlanes);
+ SDL_WriteLE16(dst, biBitCount);
+ SDL_WriteLE32(dst, biCompression);
+ SDL_WriteLE32(dst, biSizeImage);
+ SDL_WriteLE32(dst, biXPelsPerMeter);
+ SDL_WriteLE32(dst, biYPelsPerMeter);
+ SDL_WriteLE32(dst, biClrUsed);
+ SDL_WriteLE32(dst, biClrImportant);
+
+ /* Write the palette (in BGR color order) */
+ if ( surface->format->palette ) {
+ SDL_Color *colors;
+ int ncolors;
+
+ colors = surface->format->palette->colors;
+ ncolors = surface->format->palette->ncolors;
+ for ( i=0; i<ncolors; ++i ) {
+ SDL_RWwrite(dst, &colors[i].b, 1, 1);
+ SDL_RWwrite(dst, &colors[i].g, 1, 1);
+ SDL_RWwrite(dst, &colors[i].r, 1, 1);
+ SDL_RWwrite(dst, &colors[i].unused, 1, 1);
+ }
+ }
+
+ /* Write the bitmap offset */
+ bfOffBits = SDL_RWtell(dst)-fp_offset;
+ if ( SDL_RWseek(dst, fp_offset+10, RW_SEEK_SET) < 0 ) {
+ SDL_Error(SDL_EFSEEK);
+ }
+ SDL_WriteLE32(dst, bfOffBits);
+ if ( SDL_RWseek(dst, fp_offset+bfOffBits, RW_SEEK_SET) < 0 ) {
+ SDL_Error(SDL_EFSEEK);
+ }
+
+ /* Write the bitmap image upside down */
+ bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch);
+ pad = ((bw%4) ? (4-(bw%4)) : 0);
+ while ( bits > (Uint8 *)surface->pixels ) {
+ bits -= surface->pitch;
+ if ( SDL_RWwrite(dst, bits, 1, bw) != bw) {
+ SDL_Error(SDL_EFWRITE);
+ break;
+ }
+ if ( pad ) {
+ const Uint8 padbyte = 0;
+ for ( i=0; i<pad; ++i ) {
+ SDL_RWwrite(dst, &padbyte, 1, 1);
+ }
+ }
+ }
+
+ /* Write the BMP file size */
+ bfSize = SDL_RWtell(dst)-fp_offset;
+ if ( SDL_RWseek(dst, fp_offset+2, RW_SEEK_SET) < 0 ) {
+ SDL_Error(SDL_EFSEEK);
+ }
+ SDL_WriteLE32(dst, bfSize);
+ if ( SDL_RWseek(dst, fp_offset+bfSize, RW_SEEK_SET) < 0 ) {
+ SDL_Error(SDL_EFSEEK);
+ }
+
+ /* Close it up.. */
+ SDL_UnlockSurface(surface);
+ if ( surface != saveme ) {
+ SDL_FreeSurface(surface);
+ }
+ }
+
+ if ( freedst && dst ) {
+ SDL_RWclose(dst);
+ }
+ return((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1);
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_cursor.c b/distrib/sdl-1.2.15/src/video/SDL_cursor.c
new file mode 100644
index 0000000..5d747d3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_cursor.c
@@ -0,0 +1,758 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* General cursor handling code for SDL */
+
+#include "SDL_mutex.h"
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_blit.h"
+#include "SDL_sysvideo.h"
+#include "SDL_cursor_c.h"
+#include "SDL_pixels_c.h"
+#include "default_cursor.h"
+#include "../events/SDL_sysevents.h"
+#include "../events/SDL_events_c.h"
+
+/* These are static for our cursor handling code */
+volatile int SDL_cursorstate = CURSOR_VISIBLE;
+SDL_Cursor *SDL_cursor = NULL;
+static SDL_Cursor *SDL_defcursor = NULL;
+SDL_mutex *SDL_cursorlock = NULL;
+
+/* Public functions */
+void SDL_CursorQuit(void)
+{
+ if ( SDL_cursor != NULL ) {
+ SDL_Cursor *cursor;
+
+ SDL_cursorstate &= ~CURSOR_VISIBLE;
+ if ( SDL_cursor != SDL_defcursor ) {
+ SDL_FreeCursor(SDL_cursor);
+ }
+ SDL_cursor = NULL;
+ if ( SDL_defcursor != NULL ) {
+ cursor = SDL_defcursor;
+ SDL_defcursor = NULL;
+ SDL_FreeCursor(cursor);
+ }
+ }
+ if ( SDL_cursorlock != NULL ) {
+ SDL_DestroyMutex(SDL_cursorlock);
+ SDL_cursorlock = NULL;
+ }
+}
+int SDL_CursorInit(Uint32 multithreaded)
+{
+ /* We don't have mouse focus, and the cursor isn't drawn yet */
+#ifndef IPOD
+ SDL_cursorstate = CURSOR_VISIBLE;
+#endif
+
+ /* Create the default cursor */
+ if ( SDL_defcursor == NULL ) {
+ SDL_defcursor = SDL_CreateCursor(default_cdata, default_cmask,
+ DEFAULT_CWIDTH, DEFAULT_CHEIGHT,
+ DEFAULT_CHOTX, DEFAULT_CHOTY);
+ SDL_SetCursor(SDL_defcursor);
+ }
+
+ /* Create a lock if necessary */
+ if ( multithreaded ) {
+ SDL_cursorlock = SDL_CreateMutex();
+ }
+
+ /* That's it! */
+ return(0);
+}
+
+/* Multi-thread support for cursors */
+#ifndef SDL_LockCursor
+void SDL_LockCursor(void)
+{
+ if ( SDL_cursorlock ) {
+ SDL_mutexP(SDL_cursorlock);
+ }
+}
+#endif
+#ifndef SDL_UnlockCursor
+void SDL_UnlockCursor(void)
+{
+ if ( SDL_cursorlock ) {
+ SDL_mutexV(SDL_cursorlock);
+ }
+}
+#endif
+
+/* Software cursor drawing support */
+SDL_Cursor * SDL_CreateCursor (Uint8 *data, Uint8 *mask,
+ int w, int h, int hot_x, int hot_y)
+{
+ SDL_VideoDevice *video = current_video;
+ int savelen;
+ int i;
+ SDL_Cursor *cursor;
+
+ /* Make sure the width is a multiple of 8 */
+ w = ((w+7)&~7);
+
+ /* Sanity check the hot spot */
+ if ( (hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h) ) {
+ SDL_SetError("Cursor hot spot doesn't lie within cursor");
+ return(NULL);
+ }
+
+ /* Allocate memory for the cursor */
+ cursor = (SDL_Cursor *)SDL_malloc(sizeof *cursor);
+ if ( cursor == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ savelen = (w*4)*h;
+ cursor->area.x = 0;
+ cursor->area.y = 0;
+ cursor->area.w = w;
+ cursor->area.h = h;
+ cursor->hot_x = hot_x;
+ cursor->hot_y = hot_y;
+ cursor->data = (Uint8 *)SDL_malloc((w/8)*h*2);
+ cursor->mask = cursor->data+((w/8)*h);
+ cursor->save[0] = (Uint8 *)SDL_malloc(savelen*2);
+ cursor->save[1] = cursor->save[0] + savelen;
+ cursor->wm_cursor = NULL;
+ if ( ! cursor->data || ! cursor->save[0] ) {
+ SDL_FreeCursor(cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ for ( i=((w/8)*h)-1; i>=0; --i ) {
+ cursor->data[i] = data[i];
+ cursor->mask[i] = mask[i] | data[i];
+ }
+ SDL_memset(cursor->save[0], 0, savelen*2);
+
+ /* If the window manager gives us a good cursor, we're done! */
+ if ( video->CreateWMCursor ) {
+ cursor->wm_cursor = video->CreateWMCursor(video, data, mask,
+ w, h, hot_x, hot_y);
+ } else {
+ cursor->wm_cursor = NULL;
+ }
+ return(cursor);
+}
+
+/* SDL_SetCursor(NULL) can be used to force the cursor redraw,
+ if this is desired for any reason. This is used when setting
+ the video mode and when the SDL window gains the mouse focus.
+ */
+void SDL_SetCursor (SDL_Cursor *cursor)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ /* Make sure that the video subsystem has been initialized */
+ if ( ! video ) {
+ return;
+ }
+
+ /* Prevent the event thread from moving the mouse */
+ SDL_LockCursor();
+
+ /* Set the new cursor */
+ if ( cursor && (cursor != SDL_cursor) ) {
+ /* Erase the current mouse position */
+ if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
+ SDL_EraseCursor(SDL_VideoSurface);
+ } else if ( video->MoveWMCursor ) {
+ /* If the video driver is moving the cursor directly,
+ it needs to hide the old cursor before (possibly)
+ showing the new one. (But don't erase NULL cursor)
+ */
+ if ( SDL_cursor && video->ShowWMCursor ) {
+ video->ShowWMCursor(this, NULL);
+ }
+ }
+ SDL_cursor = cursor;
+ }
+
+ /* Draw the new mouse cursor */
+ if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) {
+ /* Use window manager cursor if possible */
+ int show_wm_cursor = 0;
+ if ( SDL_cursor->wm_cursor && video->ShowWMCursor ) {
+ show_wm_cursor = video->ShowWMCursor(this, SDL_cursor->wm_cursor);
+ }
+ if ( show_wm_cursor ) {
+ SDL_cursorstate &= ~CURSOR_USINGSW;
+ } else {
+ SDL_cursorstate |= CURSOR_USINGSW;
+ if ( video->ShowWMCursor ) {
+ video->ShowWMCursor(this, NULL);
+ }
+ { int x, y;
+ SDL_GetMouseState(&x, &y);
+ SDL_cursor->area.x = (x - SDL_cursor->hot_x);
+ SDL_cursor->area.y = (y - SDL_cursor->hot_y);
+ }
+ SDL_DrawCursor(SDL_VideoSurface);
+ }
+ } else {
+ /* Erase window manager mouse (cursor not visible) */
+ if ( SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW) ) {
+ SDL_EraseCursor(SDL_VideoSurface);
+ } else {
+ if ( video ) {
+ if ( video->ShowWMCursor ) {
+ video->ShowWMCursor(this, NULL);
+ }
+ }
+ }
+ }
+ SDL_UnlockCursor();
+}
+
+SDL_Cursor * SDL_GetCursor (void)
+{
+ return(SDL_cursor);
+}
+
+void SDL_FreeCursor (SDL_Cursor *cursor)
+{
+ if ( cursor ) {
+ if ( cursor == SDL_cursor ) {
+ SDL_SetCursor(SDL_defcursor);
+ }
+ if ( cursor != SDL_defcursor ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( cursor->data ) {
+ SDL_free(cursor->data);
+ }
+ if ( cursor->save[0] ) {
+ SDL_free(cursor->save[0]);
+ }
+ if ( video && cursor->wm_cursor ) {
+ if ( video->FreeWMCursor ) {
+ video->FreeWMCursor(this, cursor->wm_cursor);
+ }
+ }
+ SDL_free(cursor);
+ }
+ }
+}
+
+int SDL_ShowCursor (int toggle)
+{
+ int showing;
+
+ showing = (SDL_cursorstate & CURSOR_VISIBLE);
+ if ( toggle >= 0 ) {
+ SDL_LockCursor();
+ if ( toggle ) {
+ SDL_cursorstate |= CURSOR_VISIBLE;
+ } else {
+ SDL_cursorstate &= ~CURSOR_VISIBLE;
+ }
+ SDL_UnlockCursor();
+ if ( (SDL_cursorstate & CURSOR_VISIBLE) != showing ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ SDL_SetCursor(NULL);
+ if ( video && video->CheckMouseMode ) {
+ video->CheckMouseMode(this);
+ }
+ }
+ } else {
+ /* Query current state */ ;
+ }
+ return(showing ? 1 : 0);
+}
+
+void SDL_WarpMouse (Uint16 x, Uint16 y)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( !video || !SDL_PublicSurface ) {
+ SDL_SetError("A video mode must be set before warping mouse");
+ return;
+ }
+
+ /* If we have an offset video mode, offset the mouse coordinates */
+ if (this->screen->pitch == 0) {
+ x += this->screen->offset / this->screen->format->BytesPerPixel;
+ y += this->screen->offset;
+ } else {
+ x += (this->screen->offset % this->screen->pitch) /
+ this->screen->format->BytesPerPixel;
+ y += (this->screen->offset / this->screen->pitch);
+ }
+
+ /* This generates a mouse motion event */
+ if ( video->WarpWMCursor ) {
+ video->WarpWMCursor(this, x, y);
+ } else {
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ }
+}
+
+void SDL_MoveCursor(int x, int y)
+{
+ SDL_VideoDevice *video = current_video;
+
+ /* Erase and update the current mouse position */
+ if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
+ /* Erase and redraw mouse cursor in new position */
+ SDL_LockCursor();
+ SDL_EraseCursor(SDL_VideoSurface);
+ SDL_cursor->area.x = (x - SDL_cursor->hot_x);
+ SDL_cursor->area.y = (y - SDL_cursor->hot_y);
+ SDL_DrawCursor(SDL_VideoSurface);
+ SDL_UnlockCursor();
+ } else if ( video->MoveWMCursor ) {
+ video->MoveWMCursor(video, x, y);
+ }
+}
+
+/* Keep track of the current cursor colors */
+static int palette_changed = 1;
+static Uint8 pixels8[2];
+
+void SDL_CursorPaletteChanged(void)
+{
+ palette_changed = 1;
+}
+
+void SDL_MouseRect(SDL_Rect *area)
+{
+ int clip_diff;
+
+ *area = SDL_cursor->area;
+ if ( area->x < 0 ) {
+ area->w += area->x;
+ area->x = 0;
+ }
+ if ( area->y < 0 ) {
+ area->h += area->y;
+ area->y = 0;
+ }
+ clip_diff = (area->x+area->w)-SDL_VideoSurface->w;
+ if ( clip_diff > 0 ) {
+ area->w = area->w < clip_diff ? 0 : area->w-clip_diff;
+ }
+ clip_diff = (area->y+area->h)-SDL_VideoSurface->h;
+ if ( clip_diff > 0 ) {
+ area->h = area->h < clip_diff ? 0 : area->h-clip_diff;
+ }
+}
+
+static void SDL_DrawCursorFast(SDL_Surface *screen, SDL_Rect *area)
+{
+ const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 };
+ int i, w, h;
+ Uint8 *data, datab;
+ Uint8 *mask, maskb;
+
+ data = SDL_cursor->data + area->y * SDL_cursor->area.w/8;
+ mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8;
+ switch (screen->format->BytesPerPixel) {
+
+ case 1: {
+ Uint8 *dst;
+ int dstskip;
+
+ if ( palette_changed ) {
+ pixels8[0] = (Uint8)SDL_MapRGB(screen->format, 255, 255, 255);
+ pixels8[1] = (Uint8)SDL_MapRGB(screen->format, 0, 0, 0);
+ palette_changed = 0;
+ }
+ dst = (Uint8 *)screen->pixels +
+ (SDL_cursor->area.y+area->y)*screen->pitch +
+ SDL_cursor->area.x;
+ dstskip = screen->pitch-area->w;
+
+ for ( h=area->h; h; h-- ) {
+ for ( w=area->w/8; w; w-- ) {
+ maskb = *mask++;
+ datab = *data++;
+ for ( i=0; i<8; ++i ) {
+ if ( maskb & 0x80 ) {
+ *dst = pixels8[datab>>7];
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst++;
+ }
+ }
+ dst += dstskip;
+ }
+ }
+ break;
+
+ case 2: {
+ Uint16 *dst;
+ int dstskip;
+
+ dst = (Uint16 *)screen->pixels +
+ (SDL_cursor->area.y+area->y)*screen->pitch/2 +
+ SDL_cursor->area.x;
+ dstskip = (screen->pitch/2)-area->w;
+
+ for ( h=area->h; h; h-- ) {
+ for ( w=area->w/8; w; w-- ) {
+ maskb = *mask++;
+ datab = *data++;
+ for ( i=0; i<8; ++i ) {
+ if ( maskb & 0x80 ) {
+ *dst = (Uint16)pixels[datab>>7];
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst++;
+ }
+ }
+ dst += dstskip;
+ }
+ }
+ break;
+
+ case 3: {
+ Uint8 *dst;
+ int dstskip;
+
+ dst = (Uint8 *)screen->pixels +
+ (SDL_cursor->area.y+area->y)*screen->pitch +
+ SDL_cursor->area.x*3;
+ dstskip = screen->pitch-area->w*3;
+
+ for ( h=area->h; h; h-- ) {
+ for ( w=area->w/8; w; w-- ) {
+ maskb = *mask++;
+ datab = *data++;
+ for ( i=0; i<8; ++i ) {
+ if ( maskb & 0x80 ) {
+ SDL_memset(dst,pixels[datab>>7],3);
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst += 3;
+ }
+ }
+ dst += dstskip;
+ }
+ }
+ break;
+
+ case 4: {
+ Uint32 *dst;
+ int dstskip;
+
+ dst = (Uint32 *)screen->pixels +
+ (SDL_cursor->area.y+area->y)*screen->pitch/4 +
+ SDL_cursor->area.x;
+ dstskip = (screen->pitch/4)-area->w;
+
+ for ( h=area->h; h; h-- ) {
+ for ( w=area->w/8; w; w-- ) {
+ maskb = *mask++;
+ datab = *data++;
+ for ( i=0; i<8; ++i ) {
+ if ( maskb & 0x80 ) {
+ *dst = pixels[datab>>7];
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst++;
+ }
+ }
+ dst += dstskip;
+ }
+ }
+ break;
+ }
+}
+
+static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area)
+{
+ const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
+ int h;
+ int x, minx, maxx;
+ Uint8 *data, datab = 0;
+ Uint8 *mask, maskb = 0;
+ Uint8 *dst;
+ int dstbpp, dstskip;
+
+ data = SDL_cursor->data + area->y * SDL_cursor->area.w/8;
+ mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8;
+ dstbpp = screen->format->BytesPerPixel;
+ dst = (Uint8 *)screen->pixels +
+ (SDL_cursor->area.y+area->y)*screen->pitch +
+ SDL_cursor->area.x*dstbpp;
+ dstskip = screen->pitch-SDL_cursor->area.w*dstbpp;
+
+ minx = area->x;
+ maxx = area->x+area->w;
+ if ( screen->format->BytesPerPixel == 1 ) {
+ if ( palette_changed ) {
+ pixels8[0] = (Uint8)SDL_MapRGB(screen->format, 255, 255, 255);
+ pixels8[1] = (Uint8)SDL_MapRGB(screen->format, 0, 0, 0);
+ palette_changed = 0;
+ }
+ for ( h=area->h; h; h-- ) {
+ for ( x=0; x<SDL_cursor->area.w; ++x ) {
+ if ( (x%8) == 0 ) {
+ maskb = *mask++;
+ datab = *data++;
+ }
+ if ( (x >= minx) && (x < maxx) ) {
+ if ( maskb & 0x80 ) {
+ SDL_memset(dst, pixels8[datab>>7], dstbpp);
+ }
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst += dstbpp;
+ }
+ dst += dstskip;
+ }
+ } else {
+ for ( h=area->h; h; h-- ) {
+ for ( x=0; x<SDL_cursor->area.w; ++x ) {
+ if ( (x%8) == 0 ) {
+ maskb = *mask++;
+ datab = *data++;
+ }
+ if ( (x >= minx) && (x < maxx) ) {
+ if ( maskb & 0x80 ) {
+ SDL_memset(dst, pixels[datab>>7], dstbpp);
+ }
+ }
+ maskb <<= 1;
+ datab <<= 1;
+ dst += dstbpp;
+ }
+ dst += dstskip;
+ }
+ }
+}
+
+/* This handles the ugly work of converting the saved cursor background from
+ the pixel format of the shadow surface to that of the video surface.
+ This is only necessary when blitting from a shadow surface of a different
+ pixel format than the video surface, and using a software rendered cursor.
+*/
+static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h)
+{
+ SDL_BlitInfo info;
+ SDL_loblit RunBlit;
+
+ /* Make sure we can steal the blit mapping */
+ if ( screen->map->dst != SDL_VideoSurface ) {
+ return;
+ }
+
+ /* Set up the blit information */
+ info.s_pixels = SDL_cursor->save[1];
+ info.s_width = w;
+ info.s_height = h;
+ info.s_skip = 0;
+ info.d_pixels = SDL_cursor->save[0];
+ info.d_width = w;
+ info.d_height = h;
+ info.d_skip = 0;
+ info.aux_data = screen->map->sw_data->aux_data;
+ info.src = screen->format;
+ info.table = screen->map->table;
+ info.dst = SDL_VideoSurface->format;
+ RunBlit = screen->map->sw_data->blit;
+
+ /* Run the actual software blit */
+ RunBlit(&info);
+}
+
+void SDL_DrawCursorNoLock(SDL_Surface *screen)
+{
+ SDL_Rect area;
+
+ /* Get the mouse rectangle, clipped to the screen */
+ SDL_MouseRect(&area);
+ if ( (area.w == 0) || (area.h == 0) ) {
+ return;
+ }
+
+ /* Copy mouse background */
+ { int w, h, screenbpp;
+ Uint8 *src, *dst;
+
+ /* Set up the copy pointers */
+ screenbpp = screen->format->BytesPerPixel;
+ if ( (screen == SDL_VideoSurface) ||
+ FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) {
+ dst = SDL_cursor->save[0];
+ } else {
+ dst = SDL_cursor->save[1];
+ }
+ src = (Uint8 *)screen->pixels + area.y * screen->pitch +
+ area.x * screenbpp;
+
+ /* Perform the copy */
+ w = area.w*screenbpp;
+ h = area.h;
+ while ( h-- ) {
+ SDL_memcpy(dst, src, w);
+ dst += w;
+ src += screen->pitch;
+ }
+ }
+
+ /* Draw the mouse cursor */
+ area.x -= SDL_cursor->area.x;
+ area.y -= SDL_cursor->area.y;
+ if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) {
+ SDL_DrawCursorFast(screen, &area);
+ } else {
+ SDL_DrawCursorSlow(screen, &area);
+ }
+}
+
+void SDL_DrawCursor(SDL_Surface *screen)
+{
+ /* Lock the screen if necessary */
+ if ( screen == NULL ) {
+ return;
+ }
+ if ( SDL_MUSTLOCK(screen) ) {
+ if ( SDL_LockSurface(screen) < 0 ) {
+ return;
+ }
+ }
+
+ SDL_DrawCursorNoLock(screen);
+
+ /* Unlock the screen and update if necessary */
+ if ( SDL_MUSTLOCK(screen) ) {
+ SDL_UnlockSurface(screen);
+ }
+ if ( (screen == SDL_VideoSurface) &&
+ ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ SDL_Rect area;
+
+ SDL_MouseRect(&area);
+
+ /* This can be called before a video mode is set */
+ if ( video->UpdateRects ) {
+ video->UpdateRects(this, 1, &area);
+ }
+ }
+}
+
+void SDL_EraseCursorNoLock(SDL_Surface *screen)
+{
+ SDL_Rect area;
+
+ /* Get the mouse rectangle, clipped to the screen */
+ SDL_MouseRect(&area);
+ if ( (area.w == 0) || (area.h == 0) ) {
+ return;
+ }
+
+ /* Copy mouse background */
+ { int w, h, screenbpp;
+ Uint8 *src, *dst;
+
+ /* Set up the copy pointers */
+ screenbpp = screen->format->BytesPerPixel;
+ if ( (screen == SDL_VideoSurface) ||
+ FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) {
+ src = SDL_cursor->save[0];
+ } else {
+ src = SDL_cursor->save[1];
+ }
+ dst = (Uint8 *)screen->pixels + area.y * screen->pitch +
+ area.x * screenbpp;
+
+ /* Perform the copy */
+ w = area.w*screenbpp;
+ h = area.h;
+ while ( h-- ) {
+ SDL_memcpy(dst, src, w);
+ src += w;
+ dst += screen->pitch;
+ }
+
+ /* Perform pixel conversion on cursor background */
+ if ( src > SDL_cursor->save[1] ) {
+ SDL_ConvertCursorSave(screen, area.w, area.h);
+ }
+ }
+}
+
+void SDL_EraseCursor(SDL_Surface *screen)
+{
+ /* Lock the screen if necessary */
+ if ( screen == NULL ) {
+ return;
+ }
+ if ( SDL_MUSTLOCK(screen) ) {
+ if ( SDL_LockSurface(screen) < 0 ) {
+ return;
+ }
+ }
+
+ SDL_EraseCursorNoLock(screen);
+
+ /* Unlock the screen and update if necessary */
+ if ( SDL_MUSTLOCK(screen) ) {
+ SDL_UnlockSurface(screen);
+ }
+ if ( (screen == SDL_VideoSurface) &&
+ ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ SDL_Rect area;
+
+ SDL_MouseRect(&area);
+ if ( video->UpdateRects ) {
+ video->UpdateRects(this, 1, &area);
+ }
+ }
+}
+
+/* Reset the cursor on video mode change
+ FIXME: Keep track of all cursors, and reset them all.
+ */
+void SDL_ResetCursor(void)
+{
+ int savelen;
+
+ if ( SDL_cursor ) {
+ savelen = SDL_cursor->area.w*4*SDL_cursor->area.h;
+ SDL_cursor->area.x = 0;
+ SDL_cursor->area.y = 0;
+ SDL_memset(SDL_cursor->save[0], 0, savelen);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_cursor_c.h b/distrib/sdl-1.2.15/src/video/SDL_cursor_c.h
new file mode 100644
index 0000000..8be8df9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_cursor_c.h
@@ -0,0 +1,73 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Useful variables and functions from SDL_cursor.c */
+#include "SDL_mouse.h"
+
+extern int SDL_CursorInit(Uint32 flags);
+extern void SDL_CursorPaletteChanged(void);
+extern void SDL_DrawCursor(SDL_Surface *screen);
+extern void SDL_DrawCursorNoLock(SDL_Surface *screen);
+extern void SDL_EraseCursor(SDL_Surface *screen);
+extern void SDL_EraseCursorNoLock(SDL_Surface *screen);
+extern void SDL_UpdateCursor(SDL_Surface *screen);
+extern void SDL_ResetCursor(void);
+extern void SDL_MoveCursor(int x, int y);
+extern void SDL_CursorQuit(void);
+
+#define INLINE_MOUSELOCK
+#ifdef INLINE_MOUSELOCK
+/* Inline (macro) versions of the mouse lock functions */
+#include "SDL_mutex.h"
+
+extern SDL_mutex *SDL_cursorlock;
+
+#define SDL_LockCursor() \
+ do { \
+ if ( SDL_cursorlock ) { \
+ SDL_mutexP(SDL_cursorlock); \
+ } \
+ } while ( 0 )
+#define SDL_UnlockCursor() \
+ do { \
+ if ( SDL_cursorlock ) { \
+ SDL_mutexV(SDL_cursorlock); \
+ } \
+ } while ( 0 )
+#else
+extern void SDL_LockCursor(void);
+extern void SDL_UnlockCursor(void);
+#endif /* INLINE_MOUSELOCK */
+
+/* Only for low-level mouse cursor drawing */
+extern SDL_Cursor *SDL_cursor;
+extern void SDL_MouseRect(SDL_Rect *area);
+
+/* State definitions for the SDL cursor */
+#define CURSOR_VISIBLE 0x01
+#define CURSOR_USINGSW 0x10
+#define SHOULD_DRAWCURSOR(X) \
+ (((X)&(CURSOR_VISIBLE|CURSOR_USINGSW)) == \
+ (CURSOR_VISIBLE|CURSOR_USINGSW))
+
+extern volatile int SDL_cursorstate;
diff --git a/distrib/sdl-1.2.15/src/video/SDL_gamma.c b/distrib/sdl-1.2.15/src/video/SDL_gamma.c
new file mode 100644
index 0000000..4fd0370
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_gamma.c
@@ -0,0 +1,233 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Gamma correction support */
+
+#ifdef HAVE_MATH_H
+#include <math.h> /* Used for calculating gamma ramps */
+#else
+/* Math routines from uClibc: http://www.uclibc.org */
+#include "math_private.h"
+#include "e_sqrt.h"
+#include "e_pow.h"
+#include "e_log.h"
+#define pow(x, y) __ieee754_pow(x, y)
+#define log(x) __ieee754_log(x)
+#endif
+
+#include "SDL_sysvideo.h"
+
+
+static void CalculateGammaRamp(float gamma, Uint16 *ramp)
+{
+ int i;
+
+ /* 0.0 gamma is all black */
+ if ( gamma <= 0.0f ) {
+ for ( i=0; i<256; ++i ) {
+ ramp[i] = 0;
+ }
+ return;
+ } else
+ /* 1.0 gamma is identity */
+ if ( gamma == 1.0f ) {
+ for ( i=0; i<256; ++i ) {
+ ramp[i] = (i << 8) | i;
+ }
+ return;
+ } else
+ /* Calculate a real gamma ramp */
+ { int value;
+ gamma = 1.0f / gamma;
+ for ( i=0; i<256; ++i ) {
+ value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5);
+ if ( value > 65535 ) {
+ value = 65535;
+ }
+ ramp[i] = (Uint16)value;
+ }
+ }
+}
+static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp)
+{
+ /* The following is adapted from a post by Garrett Bass on OpenGL
+ Gamedev list, March 4, 2000.
+ */
+ float sum = 0.0f;
+ int i, count = 0;
+
+ *gamma = 1.0;
+ for ( i = 1; i < 256; ++i ) {
+ if ( (ramp[i] != 0) && (ramp[i] != 65535) ) {
+ double B = (double)i / 256.0;
+ double A = ramp[i] / 65535.0;
+ sum += (float) ( log(A) / log(B) );
+ count++;
+ }
+ }
+ if ( count && sum > 0.0f ) {
+ *gamma = 1.0f / (sum / count);
+ }
+}
+
+int SDL_SetGamma(float red, float green, float blue)
+{
+ int succeeded;
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ succeeded = -1;
+ /* Prefer using SetGammaRamp(), as it's more flexible */
+ {
+ Uint16 ramp[3][256];
+
+ CalculateGammaRamp(red, ramp[0]);
+ CalculateGammaRamp(green, ramp[1]);
+ CalculateGammaRamp(blue, ramp[2]);
+ succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]);
+ }
+ if ( (succeeded < 0) && video->SetGamma ) {
+ SDL_ClearError();
+ succeeded = video->SetGamma(this, red, green, blue);
+ }
+ return succeeded;
+}
+
+/* Calculating the gamma by integrating the gamma ramps isn't exact,
+ so this function isn't officially supported.
+*/
+int SDL_GetGamma(float *red, float *green, float *blue)
+{
+ int succeeded;
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ succeeded = -1;
+ /* Prefer using GetGammaRamp(), as it's more flexible */
+ {
+ Uint16 ramp[3][256];
+
+ succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]);
+ if ( succeeded >= 0 ) {
+ CalculateGammaFromRamp(red, ramp[0]);
+ CalculateGammaFromRamp(green, ramp[1]);
+ CalculateGammaFromRamp(blue, ramp[2]);
+ }
+ }
+ if ( (succeeded < 0) && video->GetGamma ) {
+ SDL_ClearError();
+ succeeded = video->GetGamma(this, red, green, blue);
+ }
+ return succeeded;
+}
+
+int SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue)
+{
+ int succeeded;
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ SDL_Surface *screen = SDL_PublicSurface;
+
+ /* Verify the screen parameter */
+ if ( !screen ) {
+ SDL_SetError("No video mode has been set");
+ return -1;
+ }
+
+ /* Lazily allocate the gamma tables */
+ if ( ! video->gamma ) {
+ SDL_GetGammaRamp(0, 0, 0);
+ }
+
+ /* Fill the gamma table with the new values */
+ if ( red ) {
+ SDL_memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma));
+ }
+ if ( green ) {
+ SDL_memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma));
+ }
+ if ( blue ) {
+ SDL_memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma));
+ }
+
+ /* Gamma correction always possible on split palettes */
+ if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) {
+ SDL_Palette *pal = screen->format->palette;
+
+ /* If physical palette has been set independently, use it */
+ if(video->physpal)
+ pal = video->physpal;
+
+ SDL_SetPalette(screen, SDL_PHYSPAL,
+ pal->colors, 0, pal->ncolors);
+ return 0;
+ }
+
+ /* Try to set the gamma ramp in the driver */
+ succeeded = -1;
+ if ( video->SetGammaRamp ) {
+ succeeded = video->SetGammaRamp(this, video->gamma);
+ } else {
+ SDL_SetError("Gamma ramp manipulation not supported");
+ }
+ return succeeded;
+}
+
+int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ /* Lazily allocate the gamma table */
+ if ( ! video->gamma ) {
+ video->gamma = SDL_malloc(3*256*sizeof(*video->gamma));
+ if ( ! video->gamma ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ if ( video->GetGammaRamp ) {
+ /* Get the real hardware gamma */
+ video->GetGammaRamp(this, video->gamma);
+ } else {
+ /* Assume an identity gamma */
+ int i;
+ for ( i=0; i<256; ++i ) {
+ video->gamma[0*256+i] = (i << 8) | i;
+ video->gamma[1*256+i] = (i << 8) | i;
+ video->gamma[2*256+i] = (i << 8) | i;
+ }
+ }
+ }
+
+ /* Just copy from our internal table */
+ if ( red ) {
+ SDL_memcpy(red, &video->gamma[0*256], 256*sizeof(*red));
+ }
+ if ( green ) {
+ SDL_memcpy(green, &video->gamma[1*256], 256*sizeof(*green));
+ }
+ if ( blue ) {
+ SDL_memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue));
+ }
+ return 0;
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_glfuncs.h b/distrib/sdl-1.2.15/src/video/SDL_glfuncs.h
new file mode 100644
index 0000000..fb2d964
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_glfuncs.h
@@ -0,0 +1,341 @@
+/* list of OpenGL functions sorted alphabetically
+ If you need to use a GL function from the SDL video subsystem,
+ change it's entry from SDL_PROC_UNUSED to SDL_PROC and rebuild.
+*/
+#define SDL_PROC_UNUSED(ret,func,params)
+SDL_PROC_UNUSED(void,glAccum,(GLenum,GLfloat))
+SDL_PROC_UNUSED(void,glAlphaFunc,(GLenum,GLclampf))
+SDL_PROC_UNUSED(GLboolean,glAreTexturesResident,(GLsizei,const GLuint*,GLboolean*))
+SDL_PROC_UNUSED(void,glArrayElement,(GLint))
+SDL_PROC(void,glBegin,(GLenum))
+SDL_PROC(void,glBindTexture,(GLenum,GLuint))
+SDL_PROC_UNUSED(void,glBitmap,(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*))
+SDL_PROC(void,glBlendFunc,(GLenum,GLenum))
+SDL_PROC_UNUSED(void,glCallList,(GLuint))
+SDL_PROC_UNUSED(void,glCallLists,(GLsizei,GLenum,const GLvoid*))
+SDL_PROC_UNUSED(void,glClear,(GLbitfield))
+SDL_PROC_UNUSED(void,glClearAccum,(GLfloat,GLfloat,GLfloat,GLfloat))
+SDL_PROC_UNUSED(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf))
+SDL_PROC_UNUSED(void,glClearDepth,(GLclampd))
+SDL_PROC_UNUSED(void,glClearIndex,(GLfloat))
+SDL_PROC_UNUSED(void,glClearStencil,(GLint))
+SDL_PROC_UNUSED(void,glClipPlane,(GLenum,const GLdouble*))
+SDL_PROC_UNUSED(void,glColor3b,(GLbyte,GLbyte,GLbyte))
+SDL_PROC_UNUSED(void,glColor3bv,(const GLbyte*))
+SDL_PROC_UNUSED(void,glColor3d,(GLdouble,GLdouble,GLdouble))
+SDL_PROC_UNUSED(void,glColor3dv,(const GLdouble*))
+SDL_PROC_UNUSED(void,glColor3f,(GLfloat,GLfloat,GLfloat))
+SDL_PROC_UNUSED(void,glColor3fv,(const GLfloat*))
+SDL_PROC_UNUSED(void,glColor3i,(GLint,GLint,GLint))
+SDL_PROC_UNUSED(void,glColor3iv,(const GLint*))
+SDL_PROC_UNUSED(void,glColor3s,(GLshort,GLshort,GLshort))
+SDL_PROC_UNUSED(void,glColor3sv,(const GLshort*))
+SDL_PROC_UNUSED(void,glColor3ub,(GLubyte,GLubyte,GLubyte))
+SDL_PROC_UNUSED(void,glColor3ubv,(const GLubyte*))
+SDL_PROC_UNUSED(void,glColor3ui,(GLuint,GLuint,GLuint))
+SDL_PROC_UNUSED(void,glColor3uiv,(const GLuint*))
+SDL_PROC_UNUSED(void,glColor3us,(GLushort,GLushort,GLushort))
+SDL_PROC_UNUSED(void,glColor3usv,(const GLushort*))
+SDL_PROC_UNUSED(void,glColor4b,(GLbyte,GLbyte,GLbyte,GLbyte))
+SDL_PROC_UNUSED(void,glColor4bv,(const GLbyte*))
+SDL_PROC_UNUSED(void,glColor4d,(GLdouble,GLdouble,GLdouble,GLdouble))
+SDL_PROC_UNUSED(void,glColor4dv,(const GLdouble*))
+SDL_PROC(void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat))
+SDL_PROC_UNUSED(void,glColor4fv,(const GLfloat*))
+SDL_PROC_UNUSED(void,glColor4i,(GLint,GLint,GLint,GLint))
+SDL_PROC_UNUSED(void,glColor4iv,(const GLint*))
+SDL_PROC_UNUSED(void,glColor4s,(GLshort,GLshort,GLshort,GLshort))
+SDL_PROC_UNUSED(void,glColor4sv,(const GLshort*))
+SDL_PROC_UNUSED(void,glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
+SDL_PROC_UNUSED(void,glColor4ubv,(const GLubyte *v))
+SDL_PROC_UNUSED(void,glColor4ui,(GLuint red, GLuint green, GLuint blue, GLuint alpha))
+SDL_PROC_UNUSED(void,glColor4uiv,(const GLuint *v))
+SDL_PROC_UNUSED(void,glColor4us,(GLushort red, GLushort green, GLushort blue, GLushort alpha))
+SDL_PROC_UNUSED(void,glColor4usv,(const GLushort *v))
+SDL_PROC_UNUSED(void,glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha))
+SDL_PROC_UNUSED(void,glColorMaterial,(GLenum face, GLenum mode))
+SDL_PROC_UNUSED(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer))
+SDL_PROC_UNUSED(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type))
+SDL_PROC_UNUSED(void,glCopyTexImage1D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border))
+SDL_PROC_UNUSED(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border))
+SDL_PROC_UNUSED(void,glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width))
+SDL_PROC_UNUSED(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height))
+SDL_PROC_UNUSED(void,glCullFace,(GLenum mode))
+SDL_PROC_UNUSED(void,glDeleteLists,(GLuint list, GLsizei range))
+SDL_PROC_UNUSED(void,glDeleteTextures,(GLsizei n, const GLuint *textures))
+SDL_PROC_UNUSED(void,glDepthFunc,(GLenum func))
+SDL_PROC_UNUSED(void,glDepthMask,(GLboolean flag))
+SDL_PROC_UNUSED(void,glDepthRange,(GLclampd zNear, GLclampd zFar))
+SDL_PROC(void,glDisable,(GLenum cap))
+SDL_PROC_UNUSED(void,glDisableClientState,(GLenum array))
+SDL_PROC_UNUSED(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count))
+SDL_PROC_UNUSED(void,glDrawBuffer,(GLenum mode))
+SDL_PROC_UNUSED(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices))
+SDL_PROC_UNUSED(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels))
+SDL_PROC_UNUSED(void,glEdgeFlag,(GLboolean flag))
+SDL_PROC_UNUSED(void,glEdgeFlagPointer,(GLsizei stride, const GLvoid *pointer))
+SDL_PROC_UNUSED(void,glEdgeFlagv,(const GLboolean *flag))
+SDL_PROC(void,glEnable,(GLenum cap))
+SDL_PROC_UNUSED(void,glEnableClientState,(GLenum array))
+SDL_PROC(void,glEnd,(void))
+SDL_PROC_UNUSED(void,glEndList,(void))
+SDL_PROC_UNUSED(void,glEvalCoord1d,(GLdouble u))
+SDL_PROC_UNUSED(void,glEvalCoord1dv,(const GLdouble *u))
+SDL_PROC_UNUSED(void,glEvalCoord1f,(GLfloat u))
+SDL_PROC_UNUSED(void,glEvalCoord1fv,(const GLfloat *u))
+SDL_PROC_UNUSED(void,glEvalCoord2d,(GLdouble u, GLdouble v))
+SDL_PROC_UNUSED(void,glEvalCoord2dv,(const GLdouble *u))
+SDL_PROC_UNUSED(void,glEvalCoord2f,(GLfloat u, GLfloat v))
+SDL_PROC_UNUSED(void,glEvalCoord2fv,(const GLfloat *u))
+SDL_PROC_UNUSED(void,glEvalMesh1,(GLenum mode, GLint i1, GLint i2))
+SDL_PROC_UNUSED(void,glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2))
+SDL_PROC_UNUSED(void,glEvalPoint1,(GLint i))
+SDL_PROC_UNUSED(void,glEvalPoint2,(GLint i, GLint j))
+SDL_PROC_UNUSED(void,glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer))
+SDL_PROC_UNUSED(void,glFinish,(void))
+SDL_PROC(void,glFlush,(void))
+SDL_PROC_UNUSED(void,glFogf,(GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glFogfv,(GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glFogi,(GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glFogiv,(GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glFrontFace,(GLenum mode))
+SDL_PROC_UNUSED(void,glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar))
+SDL_PROC_UNUSED(GLuint,glGenLists,(GLsizei range))
+SDL_PROC(void,glGenTextures,(GLsizei n, GLuint *textures))
+SDL_PROC_UNUSED(void,glGetBooleanv,(GLenum pname, GLboolean *params))
+SDL_PROC_UNUSED(void,glGetClipPlane,(GLenum plane, GLdouble *equation))
+SDL_PROC_UNUSED(void,glGetDoublev,(GLenum pname, GLdouble *params))
+SDL_PROC_UNUSED(GLenum,glGetError,(void))
+SDL_PROC_UNUSED(void,glGetFloatv,(GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetIntegerv,(GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetLightiv,(GLenum light, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetMapdv,(GLenum target, GLenum query, GLdouble *v))
+SDL_PROC_UNUSED(void,glGetMapfv,(GLenum target, GLenum query, GLfloat *v))
+SDL_PROC_UNUSED(void,glGetMapiv,(GLenum target, GLenum query, GLint *v))
+SDL_PROC_UNUSED(void,glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetMaterialiv,(GLenum face, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetPixelMapfv,(GLenum map, GLfloat *values))
+SDL_PROC_UNUSED(void,glGetPixelMapuiv,(GLenum map, GLuint *values))
+SDL_PROC_UNUSED(void,glGetPixelMapusv,(GLenum map, GLushort *values))
+SDL_PROC_UNUSED(void,glGetPointerv,(GLenum pname, GLvoid* *params))
+SDL_PROC_UNUSED(void,glGetPolygonStipple,(GLubyte *mask))
+SDL_PROC(const GLubyte *,glGetString,(GLenum name))
+SDL_PROC_UNUSED(void,glGetTexEnvfv,(GLenum target, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetTexEnviv,(GLenum target, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetTexGendv,(GLenum coord, GLenum pname, GLdouble *params))
+SDL_PROC_UNUSED(void,glGetTexGenfv,(GLenum coord, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetTexGeniv,(GLenum coord, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels))
+SDL_PROC_UNUSED(void,glGetTexLevelParameterfv,(GLenum target, GLint level, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glGetTexParameterfv,(GLenum target, GLenum pname, GLfloat *params))
+SDL_PROC_UNUSED(void,glGetTexParameteriv,(GLenum target, GLenum pname, GLint *params))
+SDL_PROC_UNUSED(void,glHint,(GLenum target, GLenum mode))
+SDL_PROC_UNUSED(void,glIndexMask,(GLuint mask))
+SDL_PROC_UNUSED(void,glIndexPointer,(GLenum type, GLsizei stride, const GLvoid *pointer))
+SDL_PROC_UNUSED(void,glIndexd,(GLdouble c))
+SDL_PROC_UNUSED(void,glIndexdv,(const GLdouble *c))
+SDL_PROC_UNUSED(void,glIndexf,(GLfloat c))
+SDL_PROC_UNUSED(void,glIndexfv,(const GLfloat *c))
+SDL_PROC_UNUSED(void,glIndexi,(GLint c))
+SDL_PROC_UNUSED(void,glIndexiv,(const GLint *c))
+SDL_PROC_UNUSED(void,glIndexs,(GLshort c))
+SDL_PROC_UNUSED(void,glIndexsv,(const GLshort *c))
+SDL_PROC_UNUSED(void,glIndexub,(GLubyte c))
+SDL_PROC_UNUSED(void,glIndexubv,(const GLubyte *c))
+SDL_PROC_UNUSED(void,glInitNames,(void))
+SDL_PROC_UNUSED(void,glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer))
+SDL_PROC_UNUSED(GLboolean,glIsEnabled,(GLenum cap))
+SDL_PROC_UNUSED(GLboolean,glIsList,(GLuint list))
+SDL_PROC_UNUSED(GLboolean,glIsTexture,(GLuint texture))
+SDL_PROC_UNUSED(void,glLightModelf,(GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glLightModelfv,(GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glLightModeli,(GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glLightModeliv,(GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glLightf,(GLenum light, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glLightfv,(GLenum light, GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glLighti,(GLenum light, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glLightiv,(GLenum light, GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glLineStipple,(GLint factor, GLushort pattern))
+SDL_PROC_UNUSED(void,glLineWidth,(GLfloat width))
+SDL_PROC_UNUSED(void,glListBase,(GLuint base))
+SDL_PROC(void,glLoadIdentity,(void))
+SDL_PROC_UNUSED(void,glLoadMatrixd,(const GLdouble *m))
+SDL_PROC_UNUSED(void,glLoadMatrixf,(const GLfloat *m))
+SDL_PROC_UNUSED(void,glLoadName,(GLuint name))
+SDL_PROC_UNUSED(void,glLogicOp,(GLenum opcode))
+SDL_PROC_UNUSED(void,glMap1d,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points))
+SDL_PROC_UNUSED(void,glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points))
+SDL_PROC_UNUSED(void,glMap2d,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points))
+SDL_PROC_UNUSED(void,glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points))
+SDL_PROC_UNUSED(void,glMapGrid1d,(GLint un, GLdouble u1, GLdouble u2))
+SDL_PROC_UNUSED(void,glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2))
+SDL_PROC_UNUSED(void,glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2))
+SDL_PROC_UNUSED(void,glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2))
+SDL_PROC_UNUSED(void,glMaterialf,(GLenum face, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glMateriali,(GLenum face, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glMaterialiv,(GLenum face, GLenum pname, const GLint *params))
+SDL_PROC(void,glMatrixMode,(GLenum mode))
+SDL_PROC_UNUSED(void,glMultMatrixd,(const GLdouble *m))
+SDL_PROC_UNUSED(void,glMultMatrixf,(const GLfloat *m))
+SDL_PROC_UNUSED(void,glNewList,(GLuint list, GLenum mode))
+SDL_PROC_UNUSED(void,glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz))
+SDL_PROC_UNUSED(void,glNormal3bv,(const GLbyte *v))
+SDL_PROC_UNUSED(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz))
+SDL_PROC_UNUSED(void,glNormal3dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz))
+SDL_PROC_UNUSED(void,glNormal3fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glNormal3i,(GLint nx, GLint ny, GLint nz))
+SDL_PROC_UNUSED(void,glNormal3iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glNormal3s,(GLshort nx, GLshort ny, GLshort nz))
+SDL_PROC_UNUSED(void,glNormal3sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *pointer))
+SDL_PROC(void,glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar))
+SDL_PROC_UNUSED(void,glPassThrough,(GLfloat token))
+SDL_PROC_UNUSED(void,glPixelMapfv,(GLenum map, GLsizei mapsize, const GLfloat *values))
+SDL_PROC_UNUSED(void,glPixelMapuiv,(GLenum map, GLsizei mapsize, const GLuint *values))
+SDL_PROC_UNUSED(void,glPixelMapusv,(GLenum map, GLsizei mapsize, const GLushort *values))
+SDL_PROC_UNUSED(void,glPixelStoref,(GLenum pname, GLfloat param))
+SDL_PROC(void,glPixelStorei,(GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glPixelTransferf,(GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glPixelTransferi,(GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glPixelZoom,(GLfloat xfactor, GLfloat yfactor))
+SDL_PROC_UNUSED(void,glPointSize,(GLfloat size))
+SDL_PROC_UNUSED(void,glPolygonMode,(GLenum face, GLenum mode))
+SDL_PROC_UNUSED(void,glPolygonOffset,(GLfloat factor, GLfloat units))
+SDL_PROC_UNUSED(void,glPolygonStipple,(const GLubyte *mask))
+SDL_PROC(void,glPopAttrib,(void))
+SDL_PROC(void,glPopClientAttrib,(void))
+SDL_PROC(void,glPopMatrix,(void))
+SDL_PROC_UNUSED(void,glPopName,(void))
+SDL_PROC_UNUSED(void,glPrioritizeTextures,(GLsizei n, const GLuint *textures, const GLclampf *priorities))
+SDL_PROC(void,glPushAttrib,(GLbitfield mask))
+SDL_PROC(void,glPushClientAttrib,(GLbitfield mask))
+SDL_PROC(void,glPushMatrix,(void))
+SDL_PROC_UNUSED(void,glPushName,(GLuint name))
+SDL_PROC_UNUSED(void,glRasterPos2d,(GLdouble x, GLdouble y))
+SDL_PROC_UNUSED(void,glRasterPos2dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glRasterPos2f,(GLfloat x, GLfloat y))
+SDL_PROC_UNUSED(void,glRasterPos2fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glRasterPos2i,(GLint x, GLint y))
+SDL_PROC_UNUSED(void,glRasterPos2iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glRasterPos2s,(GLshort x, GLshort y))
+SDL_PROC_UNUSED(void,glRasterPos2sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glRasterPos3d,(GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void,glRasterPos3dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glRasterPos3f,(GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void,glRasterPos3fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glRasterPos3i,(GLint x, GLint y, GLint z))
+SDL_PROC_UNUSED(void,glRasterPos3iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glRasterPos3s,(GLshort x, GLshort y, GLshort z))
+SDL_PROC_UNUSED(void,glRasterPos3sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glRasterPos4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w))
+SDL_PROC_UNUSED(void,glRasterPos4dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glRasterPos4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w))
+SDL_PROC_UNUSED(void,glRasterPos4fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glRasterPos4i,(GLint x, GLint y, GLint z, GLint w))
+SDL_PROC_UNUSED(void,glRasterPos4iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w))
+SDL_PROC_UNUSED(void,glRasterPos4sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glReadBuffer,(GLenum mode))
+SDL_PROC_UNUSED(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels))
+SDL_PROC_UNUSED(void,glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2))
+SDL_PROC_UNUSED(void,glRectdv,(const GLdouble *v1, const GLdouble *v2))
+SDL_PROC_UNUSED(void,glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2))
+SDL_PROC_UNUSED(void,glRectfv,(const GLfloat *v1, const GLfloat *v2))
+SDL_PROC_UNUSED(void,glRecti,(GLint x1, GLint y1, GLint x2, GLint y2))
+SDL_PROC_UNUSED(void,glRectiv,(const GLint *v1, const GLint *v2))
+SDL_PROC_UNUSED(void,glRects,(GLshort x1, GLshort y1, GLshort x2, GLshort y2))
+SDL_PROC_UNUSED(void,glRectsv,(const GLshort *v1, const GLshort *v2))
+SDL_PROC_UNUSED(GLint,glRenderMode,(GLenum mode))
+SDL_PROC_UNUSED(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void,glScaled,(GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void,glScalef,(GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height))
+SDL_PROC_UNUSED(void,glSelectBuffer,(GLsizei size, GLuint *buffer))
+SDL_PROC_UNUSED(void,glShadeModel,(GLenum mode))
+SDL_PROC_UNUSED(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask))
+SDL_PROC_UNUSED(void,glStencilMask,(GLuint mask))
+SDL_PROC_UNUSED(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass))
+SDL_PROC_UNUSED(void,glTexCoord1d,(GLdouble s))
+SDL_PROC_UNUSED(void,glTexCoord1dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glTexCoord1f,(GLfloat s))
+SDL_PROC_UNUSED(void,glTexCoord1fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glTexCoord1i,(GLint s))
+SDL_PROC_UNUSED(void,glTexCoord1iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glTexCoord1s,(GLshort s))
+SDL_PROC_UNUSED(void,glTexCoord1sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glTexCoord2d,(GLdouble s, GLdouble t))
+SDL_PROC_UNUSED(void,glTexCoord2dv,(const GLdouble *v))
+SDL_PROC(void,glTexCoord2f,(GLfloat s, GLfloat t))
+SDL_PROC_UNUSED(void,glTexCoord2fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glTexCoord2i,(GLint s, GLint t))
+SDL_PROC_UNUSED(void,glTexCoord2iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glTexCoord2s,(GLshort s, GLshort t))
+SDL_PROC_UNUSED(void,glTexCoord2sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glTexCoord3d,(GLdouble s, GLdouble t, GLdouble r))
+SDL_PROC_UNUSED(void,glTexCoord3dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glTexCoord3f,(GLfloat s, GLfloat t, GLfloat r))
+SDL_PROC_UNUSED(void,glTexCoord3fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glTexCoord3i,(GLint s, GLint t, GLint r))
+SDL_PROC_UNUSED(void,glTexCoord3iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glTexCoord3s,(GLshort s, GLshort t, GLshort r))
+SDL_PROC_UNUSED(void,glTexCoord3sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glTexCoord4d,(GLdouble s, GLdouble t, GLdouble r, GLdouble q))
+SDL_PROC_UNUSED(void,glTexCoord4dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glTexCoord4f,(GLfloat s, GLfloat t, GLfloat r, GLfloat q))
+SDL_PROC_UNUSED(void,glTexCoord4fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glTexCoord4i,(GLint s, GLint t, GLint r, GLint q))
+SDL_PROC_UNUSED(void,glTexCoord4iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glTexCoord4s,(GLshort s, GLshort t, GLshort r, GLshort q))
+SDL_PROC_UNUSED(void,glTexCoord4sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer))
+SDL_PROC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glTexEnvi,(GLenum target, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glTexEnviv,(GLenum target, GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glTexGend,(GLenum coord, GLenum pname, GLdouble param))
+SDL_PROC_UNUSED(void,glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params))
+SDL_PROC_UNUSED(void,glTexGenf,(GLenum coord, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params))
+SDL_PROC_UNUSED(void,glTexGeni,(GLenum coord, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glTexGeniv,(GLenum coord, GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glTexImage1D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels))
+SDL_PROC(void,glTexImage2D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels))
+SDL_PROC_UNUSED(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params))
+SDL_PROC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void,glTexParameteriv,(GLenum target, GLenum pname, const GLint *params))
+SDL_PROC_UNUSED(void,glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels))
+SDL_PROC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels))
+SDL_PROC_UNUSED(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void,glVertex2d,(GLdouble x, GLdouble y))
+SDL_PROC_UNUSED(void,glVertex2dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glVertex2f,(GLfloat x, GLfloat y))
+SDL_PROC_UNUSED(void,glVertex2fv,(const GLfloat *v))
+SDL_PROC(void,glVertex2i,(GLint x, GLint y))
+SDL_PROC_UNUSED(void,glVertex2iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glVertex2s,(GLshort x, GLshort y))
+SDL_PROC_UNUSED(void,glVertex2sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glVertex3d,(GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void,glVertex3dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void,glVertex3fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glVertex3i,(GLint x, GLint y, GLint z))
+SDL_PROC_UNUSED(void,glVertex3iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glVertex3s,(GLshort x, GLshort y, GLshort z))
+SDL_PROC_UNUSED(void,glVertex3sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glVertex4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w))
+SDL_PROC_UNUSED(void,glVertex4dv,(const GLdouble *v))
+SDL_PROC_UNUSED(void,glVertex4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w))
+SDL_PROC_UNUSED(void,glVertex4fv,(const GLfloat *v))
+SDL_PROC_UNUSED(void,glVertex4i,(GLint x, GLint y, GLint z, GLint w))
+SDL_PROC_UNUSED(void,glVertex4iv,(const GLint *v))
+SDL_PROC_UNUSED(void,glVertex4s,(GLshort x, GLshort y, GLshort z, GLshort w))
+SDL_PROC_UNUSED(void,glVertex4sv,(const GLshort *v))
+SDL_PROC_UNUSED(void,glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer))
+SDL_PROC(void,glViewport,(GLint x, GLint y, GLsizei width, GLsizei height))
diff --git a/distrib/sdl-1.2.15/src/video/SDL_leaks.h b/distrib/sdl-1.2.15/src/video/SDL_leaks.h
new file mode 100644
index 0000000..74495c6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_leaks.h
@@ -0,0 +1,31 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Define this if you want surface leak detection code enabled */
+/*#define CHECK_LEAKS*/
+
+/* Global variables used to check leaks in code using SDL */
+
+#ifdef CHECK_LEAKS
+extern int surfaces_allocated;
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/SDL_pixels.c b/distrib/sdl-1.2.15/src/video/SDL_pixels.c
new file mode 100644
index 0000000..1a7fd51
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_pixels.c
@@ -0,0 +1,626 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* General (mostly internal) pixel/color manipulation routines for SDL */
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_pixels_c.h"
+#include "SDL_RLEaccel_c.h"
+
+/* Helper functions */
+/*
+ * Allocate a pixel format structure and fill it according to the given info.
+ */
+SDL_PixelFormat *SDL_AllocFormat(int bpp,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ SDL_PixelFormat *format;
+ Uint32 mask;
+
+ /* Allocate an empty pixel format structure */
+ format = SDL_malloc(sizeof(*format));
+ if ( format == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(format, 0, sizeof(*format));
+ format->alpha = SDL_ALPHA_OPAQUE;
+
+ /* Set up the format */
+ format->BitsPerPixel = bpp;
+ format->BytesPerPixel = (bpp+7)/8;
+ if ( Rmask || Bmask || Gmask ) { /* Packed pixels with custom mask */
+ format->palette = NULL;
+ format->Rshift = 0;
+ format->Rloss = 8;
+ if ( Rmask ) {
+ for ( mask = Rmask; !(mask&0x01); mask >>= 1 )
+ ++format->Rshift;
+ for ( ; (mask&0x01); mask >>= 1 )
+ --format->Rloss;
+ }
+ format->Gshift = 0;
+ format->Gloss = 8;
+ if ( Gmask ) {
+ for ( mask = Gmask; !(mask&0x01); mask >>= 1 )
+ ++format->Gshift;
+ for ( ; (mask&0x01); mask >>= 1 )
+ --format->Gloss;
+ }
+ format->Bshift = 0;
+ format->Bloss = 8;
+ if ( Bmask ) {
+ for ( mask = Bmask; !(mask&0x01); mask >>= 1 )
+ ++format->Bshift;
+ for ( ; (mask&0x01); mask >>= 1 )
+ --format->Bloss;
+ }
+ format->Ashift = 0;
+ format->Aloss = 8;
+ if ( Amask ) {
+ for ( mask = Amask; !(mask&0x01); mask >>= 1 )
+ ++format->Ashift;
+ for ( ; (mask&0x01); mask >>= 1 )
+ --format->Aloss;
+ }
+ format->Rmask = Rmask;
+ format->Gmask = Gmask;
+ format->Bmask = Bmask;
+ format->Amask = Amask;
+ } else if ( bpp > 8 ) { /* Packed pixels with standard mask */
+ /* R-G-B */
+ if ( bpp > 24 )
+ bpp = 24;
+ format->Rloss = 8-(bpp/3);
+ format->Gloss = 8-(bpp/3)-(bpp%3);
+ format->Bloss = 8-(bpp/3);
+ format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3);
+ format->Gshift = (bpp/3);
+ format->Bshift = 0;
+ format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift);
+ format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift);
+ format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift);
+ } else {
+ /* Palettized formats have no mask info */
+ format->Rloss = 8;
+ format->Gloss = 8;
+ format->Bloss = 8;
+ format->Aloss = 8;
+ format->Rshift = 0;
+ format->Gshift = 0;
+ format->Bshift = 0;
+ format->Ashift = 0;
+ format->Rmask = 0;
+ format->Gmask = 0;
+ format->Bmask = 0;
+ format->Amask = 0;
+ }
+ if ( bpp <= 8 ) { /* Palettized mode */
+ int ncolors = 1<<bpp;
+#ifdef DEBUG_PALETTE
+ fprintf(stderr,"bpp=%d ncolors=%d\n",bpp,ncolors);
+#endif
+ format->palette = (SDL_Palette *)SDL_malloc(sizeof(SDL_Palette));
+ if ( format->palette == NULL ) {
+ SDL_FreeFormat(format);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ (format->palette)->ncolors = ncolors;
+ (format->palette)->colors = (SDL_Color *)SDL_malloc(
+ (format->palette)->ncolors*sizeof(SDL_Color));
+ if ( (format->palette)->colors == NULL ) {
+ SDL_FreeFormat(format);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ if ( Rmask || Bmask || Gmask ) {
+ /* create palette according to masks */
+ int i;
+ int Rm=0,Gm=0,Bm=0;
+ int Rw=0,Gw=0,Bw=0;
+#ifdef ENABLE_PALETTE_ALPHA
+ int Am=0,Aw=0;
+#endif
+ if(Rmask)
+ {
+ Rw=8-format->Rloss;
+ for(i=format->Rloss;i>0;i-=Rw)
+ Rm|=1<<i;
+ }
+#ifdef DEBUG_PALETTE
+ fprintf(stderr,"Rw=%d Rm=0x%02X\n",Rw,Rm);
+#endif
+ if(Gmask)
+ {
+ Gw=8-format->Gloss;
+ for(i=format->Gloss;i>0;i-=Gw)
+ Gm|=1<<i;
+ }
+#ifdef DEBUG_PALETTE
+ fprintf(stderr,"Gw=%d Gm=0x%02X\n",Gw,Gm);
+#endif
+ if(Bmask)
+ {
+ Bw=8-format->Bloss;
+ for(i=format->Bloss;i>0;i-=Bw)
+ Bm|=1<<i;
+ }
+#ifdef DEBUG_PALETTE
+ fprintf(stderr,"Bw=%d Bm=0x%02X\n",Bw,Bm);
+#endif
+#ifdef ENABLE_PALETTE_ALPHA
+ if(Amask)
+ {
+ Aw=8-format->Aloss;
+ for(i=format->Aloss;i>0;i-=Aw)
+ Am|=1<<i;
+ }
+# ifdef DEBUG_PALETTE
+ fprintf(stderr,"Aw=%d Am=0x%02X\n",Aw,Am);
+# endif
+#endif
+ for(i=0; i < ncolors; ++i) {
+ int r,g,b;
+ r=(i&Rmask)>>format->Rshift;
+ r=(r<<format->Rloss)|((r*Rm)>>Rw);
+ format->palette->colors[i].r=r;
+
+ g=(i&Gmask)>>format->Gshift;
+ g=(g<<format->Gloss)|((g*Gm)>>Gw);
+ format->palette->colors[i].g=g;
+
+ b=(i&Bmask)>>format->Bshift;
+ b=(b<<format->Bloss)|((b*Bm)>>Bw);
+ format->palette->colors[i].b=b;
+
+#ifdef ENABLE_PALETTE_ALPHA
+ a=(i&Amask)>>format->Ashift;
+ a=(a<<format->Aloss)|((a*Am)>>Aw);
+ format->palette->colors[i].unused=a;
+#else
+ format->palette->colors[i].unused=0;
+#endif
+ }
+ } else if ( ncolors == 2 ) {
+ /* Create a black and white bitmap palette */
+ format->palette->colors[0].r = 0xFF;
+ format->palette->colors[0].g = 0xFF;
+ format->palette->colors[0].b = 0xFF;
+ format->palette->colors[1].r = 0x00;
+ format->palette->colors[1].g = 0x00;
+ format->palette->colors[1].b = 0x00;
+ } else {
+ /* Create an empty palette */
+ SDL_memset((format->palette)->colors, 0,
+ (format->palette)->ncolors*sizeof(SDL_Color));
+ }
+ }
+ return(format);
+}
+SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ if ( surface->format ) {
+ SDL_FreeFormat(surface->format);
+ SDL_FormatChanged(surface);
+ }
+ surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
+ return surface->format;
+}
+
+/*
+ * Change any previous mappings from/to the new surface format
+ */
+void SDL_FormatChanged(SDL_Surface *surface)
+{
+ static int format_version = 0;
+ ++format_version;
+ if ( format_version < 0 ) { /* It wrapped... */
+ format_version = 1;
+ }
+ surface->format_version = format_version;
+ SDL_InvalidateMap(surface->map);
+}
+/*
+ * Free a previously allocated format structure
+ */
+void SDL_FreeFormat(SDL_PixelFormat *format)
+{
+ if ( format ) {
+ if ( format->palette ) {
+ if ( format->palette->colors ) {
+ SDL_free(format->palette->colors);
+ }
+ SDL_free(format->palette);
+ }
+ SDL_free(format);
+ }
+}
+/*
+ * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors
+ */
+void SDL_DitherColors(SDL_Color *colors, int bpp)
+{
+ int i;
+ if(bpp != 8)
+ return; /* only 8bpp supported right now */
+
+ for(i = 0; i < 256; i++) {
+ int r, g, b;
+ /* map each bit field to the full [0, 255] interval,
+ so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */
+ r = i & 0xe0;
+ r |= r >> 3 | r >> 6;
+ colors[i].r = r;
+ g = (i << 3) & 0xe0;
+ g |= g >> 3 | g >> 6;
+ colors[i].g = g;
+ b = i & 0x3;
+ b |= b << 2;
+ b |= b << 4;
+ colors[i].b = b;
+ }
+}
+/*
+ * Calculate the pad-aligned scanline width of a surface
+ */
+Uint16 SDL_CalculatePitch(SDL_Surface *surface)
+{
+ Uint16 pitch;
+
+ /* Surface should be 4-byte aligned for speed */
+ pitch = surface->w*surface->format->BytesPerPixel;
+ switch (surface->format->BitsPerPixel) {
+ case 1:
+ pitch = (pitch+7)/8;
+ break;
+ case 4:
+ pitch = (pitch+1)/2;
+ break;
+ default:
+ break;
+ }
+ pitch = (pitch + 3) & ~3; /* 4-byte aligning */
+ return(pitch);
+}
+/*
+ * Match an RGB value to a particular palette index
+ */
+Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b)
+{
+ /* Do colorspace distance matching */
+ unsigned int smallest;
+ unsigned int distance;
+ int rd, gd, bd;
+ int i;
+ Uint8 pixel=0;
+
+ smallest = ~0;
+ for ( i=0; i<pal->ncolors; ++i ) {
+ rd = pal->colors[i].r - r;
+ gd = pal->colors[i].g - g;
+ bd = pal->colors[i].b - b;
+ distance = (rd*rd)+(gd*gd)+(bd*bd);
+ if ( distance < smallest ) {
+ pixel = i;
+ if ( distance == 0 ) { /* Perfect match! */
+ break;
+ }
+ smallest = distance;
+ }
+ }
+ return(pixel);
+}
+
+/* Find the opaque pixel value corresponding to an RGB triple */
+Uint32 SDL_MapRGB
+(const SDL_PixelFormat * const format,
+ const Uint8 r, const Uint8 g, const Uint8 b)
+{
+ if ( format->palette == NULL ) {
+ return (r >> format->Rloss) << format->Rshift
+ | (g >> format->Gloss) << format->Gshift
+ | (b >> format->Bloss) << format->Bshift
+ | format->Amask;
+ } else {
+ return SDL_FindColor(format->palette, r, g, b);
+ }
+}
+
+/* Find the pixel value corresponding to an RGBA quadruple */
+Uint32 SDL_MapRGBA
+(const SDL_PixelFormat * const format,
+ const Uint8 r, const Uint8 g, const Uint8 b, const Uint8 a)
+{
+ if ( format->palette == NULL ) {
+ return (r >> format->Rloss) << format->Rshift
+ | (g >> format->Gloss) << format->Gshift
+ | (b >> format->Bloss) << format->Bshift
+ | ((a >> format->Aloss) << format->Ashift & format->Amask);
+ } else {
+ return SDL_FindColor(format->palette, r, g, b);
+ }
+}
+
+void SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * const fmt,
+ Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
+{
+ if ( fmt->palette == NULL ) {
+ /*
+ * This makes sure that the result is mapped to the
+ * interval [0..255], and the maximum value for each
+ * component is 255. This is important to make sure
+ * that white is indeed reported as (255, 255, 255),
+ * and that opaque alpha is 255.
+ * This only works for RGB bit fields at least 4 bit
+ * wide, which is almost always the case.
+ */
+ unsigned v;
+ v = (pixel & fmt->Rmask) >> fmt->Rshift;
+ *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1)));
+ v = (pixel & fmt->Gmask) >> fmt->Gshift;
+ *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1)));
+ v = (pixel & fmt->Bmask) >> fmt->Bshift;
+ *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1)));
+ if(fmt->Amask) {
+ v = (pixel & fmt->Amask) >> fmt->Ashift;
+ *a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1)));
+ } else {
+ *a = SDL_ALPHA_OPAQUE;
+ }
+ } else {
+ *r = fmt->palette->colors[pixel].r;
+ *g = fmt->palette->colors[pixel].g;
+ *b = fmt->palette->colors[pixel].b;
+ *a = SDL_ALPHA_OPAQUE;
+ }
+}
+
+void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * const fmt,
+ Uint8 *r,Uint8 *g,Uint8 *b)
+{
+ if ( fmt->palette == NULL ) {
+ /* the note for SDL_GetRGBA above applies here too */
+ unsigned v;
+ v = (pixel & fmt->Rmask) >> fmt->Rshift;
+ *r = (v << fmt->Rloss) + (v >> (8 - (fmt->Rloss << 1)));
+ v = (pixel & fmt->Gmask) >> fmt->Gshift;
+ *g = (v << fmt->Gloss) + (v >> (8 - (fmt->Gloss << 1)));
+ v = (pixel & fmt->Bmask) >> fmt->Bshift;
+ *b = (v << fmt->Bloss) + (v >> (8 - (fmt->Bloss << 1)));
+ } else {
+ *r = fmt->palette->colors[pixel].r;
+ *g = fmt->palette->colors[pixel].g;
+ *b = fmt->palette->colors[pixel].b;
+ }
+}
+
+/* Apply gamma to a set of colors - this is easy. :) */
+void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output,
+ int ncolors)
+{
+ int i;
+
+ for ( i=0; i<ncolors; ++i ) {
+ output[i].r = gamma[0*256 + colors[i].r] >> 8;
+ output[i].g = gamma[1*256 + colors[i].g] >> 8;
+ output[i].b = gamma[2*256 + colors[i].b] >> 8;
+ }
+}
+
+/* Map from Palette to Palette */
+static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical)
+{
+ Uint8 *map;
+ int i;
+
+ if ( identical ) {
+ if ( src->ncolors <= dst->ncolors ) {
+ /* If an identical palette, no need to map */
+ if ( SDL_memcmp(src->colors, dst->colors, src->ncolors*
+ sizeof(SDL_Color)) == 0 ) {
+ *identical = 1;
+ return(NULL);
+ }
+ }
+ *identical = 0;
+ }
+ map = (Uint8 *)SDL_malloc(src->ncolors);
+ if ( map == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ for ( i=0; i<src->ncolors; ++i ) {
+ map[i] = SDL_FindColor(dst,
+ src->colors[i].r, src->colors[i].g, src->colors[i].b);
+ }
+ return(map);
+}
+/* Map from Palette to BitField */
+static Uint8 *Map1toN(SDL_PixelFormat *src, SDL_PixelFormat *dst)
+{
+ Uint8 *map;
+ int i;
+ int bpp;
+ unsigned alpha;
+ SDL_Palette *pal = src->palette;
+
+ bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
+ map = (Uint8 *)SDL_malloc(pal->ncolors*bpp);
+ if ( map == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ alpha = dst->Amask ? src->alpha : 0;
+ /* We memory copy to the pixel map so the endianness is preserved */
+ for ( i=0; i<pal->ncolors; ++i ) {
+ ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst,
+ pal->colors[i].r, pal->colors[i].g,
+ pal->colors[i].b, alpha);
+ }
+ return(map);
+}
+/* Map from BitField to Dithered-Palette to Palette */
+static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_PixelFormat *dst, int *identical)
+{
+ /* Generate a 256 color dither palette */
+ SDL_Palette dithered;
+ SDL_Color colors[256];
+ SDL_Palette *pal = dst->palette;
+
+ /* SDL_DitherColors does not initialize the 'unused' component of colors,
+ but Map1to1 compares it against pal, so we should initialize it. */
+ SDL_memset(colors, 0, sizeof(colors));
+
+ dithered.ncolors = 256;
+ SDL_DitherColors(colors, 8);
+ dithered.colors = colors;
+ return(Map1to1(&dithered, pal, identical));
+}
+
+SDL_BlitMap *SDL_AllocBlitMap(void)
+{
+ SDL_BlitMap *map;
+
+ /* Allocate the empty map */
+ map = (SDL_BlitMap *)SDL_malloc(sizeof(*map));
+ if ( map == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(map, 0, sizeof(*map));
+
+ /* Allocate the software blit data */
+ map->sw_data = (struct private_swaccel *)SDL_malloc(sizeof(*map->sw_data));
+ if ( map->sw_data == NULL ) {
+ SDL_FreeBlitMap(map);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(map->sw_data, 0, sizeof(*map->sw_data));
+
+ /* It's ready to go */
+ return(map);
+}
+void SDL_InvalidateMap(SDL_BlitMap *map)
+{
+ if ( ! map ) {
+ return;
+ }
+ map->dst = NULL;
+ map->format_version = (unsigned int)-1;
+ if ( map->table ) {
+ SDL_free(map->table);
+ map->table = NULL;
+ }
+}
+int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst)
+{
+ SDL_PixelFormat *srcfmt;
+ SDL_PixelFormat *dstfmt;
+ SDL_BlitMap *map;
+
+ /* Clear out any previous mapping */
+ map = src->map;
+ if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ SDL_UnRLESurface(src, 1);
+ }
+ SDL_InvalidateMap(map);
+
+ /* Figure out what kind of mapping we're doing */
+ map->identity = 0;
+ srcfmt = src->format;
+ dstfmt = dst->format;
+ switch (srcfmt->BytesPerPixel) {
+ case 1:
+ switch (dstfmt->BytesPerPixel) {
+ case 1:
+ /* Palette --> Palette */
+ /* If both SDL_HWSURFACE, assume have same palette */
+ if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
+ ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) {
+ map->identity = 1;
+ } else {
+ map->table = Map1to1(srcfmt->palette,
+ dstfmt->palette, &map->identity);
+ }
+ if ( ! map->identity ) {
+ if ( map->table == NULL ) {
+ return(-1);
+ }
+ }
+ if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel)
+ map->identity = 0;
+ break;
+
+ default:
+ /* Palette --> BitField */
+ map->table = Map1toN(srcfmt, dstfmt);
+ if ( map->table == NULL ) {
+ return(-1);
+ }
+ break;
+ }
+ break;
+ default:
+ switch (dstfmt->BytesPerPixel) {
+ case 1:
+ /* BitField --> Palette */
+ map->table = MapNto1(srcfmt, dstfmt, &map->identity);
+ if ( ! map->identity ) {
+ if ( map->table == NULL ) {
+ return(-1);
+ }
+ }
+ map->identity = 0; /* Don't optimize to copy */
+ break;
+ default:
+ /* BitField --> BitField */
+ if ( FORMAT_EQUAL(srcfmt, dstfmt) )
+ map->identity = 1;
+ break;
+ }
+ break;
+ }
+
+ map->dst = dst;
+ map->format_version = dst->format_version;
+
+ /* Choose your blitters wisely */
+ return(SDL_CalculateBlit(src));
+}
+void SDL_FreeBlitMap(SDL_BlitMap *map)
+{
+ if ( map ) {
+ SDL_InvalidateMap(map);
+ if ( map->sw_data != NULL ) {
+ SDL_free(map->sw_data);
+ }
+ SDL_free(map);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_pixels_c.h b/distrib/sdl-1.2.15/src/video/SDL_pixels_c.h
new file mode 100644
index 0000000..76759e2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_pixels_c.h
@@ -0,0 +1,46 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Useful functions and variables from SDL_pixel.c */
+
+#include "SDL_blit.h"
+
+/* Pixel format functions */
+extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
+extern SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
+extern void SDL_FormatChanged(SDL_Surface *surface);
+extern void SDL_FreeFormat(SDL_PixelFormat *format);
+
+/* Blit mapping functions */
+extern SDL_BlitMap *SDL_AllocBlitMap(void);
+extern void SDL_InvalidateMap(SDL_BlitMap *map);
+extern int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst);
+extern void SDL_FreeBlitMap(SDL_BlitMap *map);
+
+/* Miscellaneous functions */
+extern Uint16 SDL_CalculatePitch(SDL_Surface *surface);
+extern void SDL_DitherColors(SDL_Color *colors, int bpp);
+extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b);
+extern void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, int ncolors);
diff --git a/distrib/sdl-1.2.15/src/video/SDL_stretch.c b/distrib/sdl-1.2.15/src/video/SDL_stretch.c
new file mode 100644
index 0000000..7ce401f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_stretch.c
@@ -0,0 +1,358 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This a stretch blit implementation based on ideas given to me by
+ Tomasz Cejner - thanks! :)
+
+ April 27, 2000 - Sam Lantinga
+*/
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+/* This isn't ready for general consumption yet - it should be folded
+ into the general blitting mechanism.
+*/
+
+#if ((defined(_MFC_VER) && defined(_M_IX86)/* && !defined(_WIN32_WCE) still needed? */) || \
+ defined(__WATCOMC__) || \
+ (defined(__GNUC__) && defined(__i386__))) && SDL_ASSEMBLY_ROUTINES
+/* There's a bug with gcc 4.4.1 and -O2 where srcp doesn't get the correct
+ * value after the first scanline. FIXME? */
+/*#define USE_ASM_STRETCH*/
+#endif
+
+#ifdef USE_ASM_STRETCH
+
+#ifdef HAVE_MPROTECT
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+#ifdef __GNUC__
+#define PAGE_ALIGNED __attribute__((__aligned__(4096)))
+#else
+#define PAGE_ALIGNED
+#endif
+
+#if defined(_M_IX86) || defined(i386)
+#define PREFIX16 0x66
+#define STORE_BYTE 0xAA
+#define STORE_WORD 0xAB
+#define LOAD_BYTE 0xAC
+#define LOAD_WORD 0xAD
+#define RETURN 0xC3
+#else
+#error Need assembly opcodes for this architecture
+#endif
+
+static unsigned char copy_row[4096] PAGE_ALIGNED;
+
+static int generate_rowbytes(int src_w, int dst_w, int bpp)
+{
+ static struct {
+ int bpp;
+ int src_w;
+ int dst_w;
+ int status;
+ } last;
+
+ int i;
+ int pos, inc;
+ unsigned char *eip, *fence;
+ unsigned char load, store;
+
+ /* See if we need to regenerate the copy buffer */
+ if ( (src_w == last.src_w) &&
+ (dst_w == last.dst_w) && (bpp == last.bpp) ) {
+ return(last.status);
+ }
+ last.bpp = bpp;
+ last.src_w = src_w;
+ last.dst_w = dst_w;
+ last.status = -1;
+
+ switch (bpp) {
+ case 1:
+ load = LOAD_BYTE;
+ store = STORE_BYTE;
+ break;
+ case 2:
+ case 4:
+ load = LOAD_WORD;
+ store = STORE_WORD;
+ break;
+ default:
+ SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
+ return(-1);
+ }
+#ifdef HAVE_MPROTECT
+ /* Make the code writeable */
+ if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_WRITE) < 0 ) {
+ SDL_SetError("Couldn't make copy buffer writeable");
+ return(-1);
+ }
+#endif
+ pos = 0x10000;
+ inc = (src_w << 16) / dst_w;
+ eip = copy_row;
+ fence = copy_row+sizeof(copy_row)-2;
+ for ( i=0; i<dst_w && eip < end; ++i ) {
+ while ( pos >= 0x10000L ) {
+ if ( eip == fence ) {
+ return -1;
+ }
+ if ( bpp == 2 ) {
+ *eip++ = PREFIX16;
+ }
+ *eip++ = load;
+ pos -= 0x10000L;
+ }
+ if ( eip == fence ) {
+ return -1;
+ }
+ if ( bpp == 2 ) {
+ *eip++ = PREFIX16;
+ }
+ *eip++ = store;
+ pos += inc;
+ }
+ *eip++ = RETURN;
+
+#ifdef HAVE_MPROTECT
+ /* Make the code executable but not writeable */
+ if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_EXEC) < 0 ) {
+ SDL_SetError("Couldn't make copy buffer executable");
+ return(-1);
+ }
+#endif
+ last.status = 0;
+ return(0);
+}
+
+#endif /* USE_ASM_STRETCH */
+
+#define DEFINE_COPY_ROW(name, type) \
+void name(type *src, int src_w, type *dst, int dst_w) \
+{ \
+ int i; \
+ int pos, inc; \
+ type pixel = 0; \
+ \
+ pos = 0x10000; \
+ inc = (src_w << 16) / dst_w; \
+ for ( i=dst_w; i>0; --i ) { \
+ while ( pos >= 0x10000L ) { \
+ pixel = *src++; \
+ pos -= 0x10000L; \
+ } \
+ *dst++ = pixel; \
+ pos += inc; \
+ } \
+}
+DEFINE_COPY_ROW(copy_row1, Uint8)
+DEFINE_COPY_ROW(copy_row2, Uint16)
+DEFINE_COPY_ROW(copy_row4, Uint32)
+
+/* The ASM code doesn't handle 24-bpp stretch blits */
+void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
+{
+ int i;
+ int pos, inc;
+ Uint8 pixel[3] = { 0, 0, 0 };
+
+ pos = 0x10000;
+ inc = (src_w << 16) / dst_w;
+ for ( i=dst_w; i>0; --i ) {
+ while ( pos >= 0x10000L ) {
+ pixel[0] = *src++;
+ pixel[1] = *src++;
+ pixel[2] = *src++;
+ pos -= 0x10000L;
+ }
+ *dst++ = pixel[0];
+ *dst++ = pixel[1];
+ *dst++ = pixel[2];
+ pos += inc;
+ }
+}
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int src_locked;
+ int dst_locked;
+ int pos, inc;
+ int dst_maxrow;
+ int src_row, dst_row;
+ Uint8 *srcp = NULL;
+ Uint8 *dstp;
+ SDL_Rect full_src;
+ SDL_Rect full_dst;
+#ifdef USE_ASM_STRETCH
+ SDL_bool use_asm = SDL_TRUE;
+#ifdef __GNUC__
+ int u1, u2;
+#endif
+#endif /* USE_ASM_STRETCH */
+ const int bpp = dst->format->BytesPerPixel;
+
+ if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
+ SDL_SetError("Only works with same format surfaces");
+ return(-1);
+ }
+
+ /* Verify the blit rectangles */
+ if ( srcrect ) {
+ if ( (srcrect->x < 0) || (srcrect->y < 0) ||
+ ((srcrect->x+srcrect->w) > src->w) ||
+ ((srcrect->y+srcrect->h) > src->h) ) {
+ SDL_SetError("Invalid source blit rectangle");
+ return(-1);
+ }
+ } else {
+ full_src.x = 0;
+ full_src.y = 0;
+ full_src.w = src->w;
+ full_src.h = src->h;
+ srcrect = &full_src;
+ }
+ if ( dstrect ) {
+ if ( (dstrect->x < 0) || (dstrect->y < 0) ||
+ ((dstrect->x+dstrect->w) > dst->w) ||
+ ((dstrect->y+dstrect->h) > dst->h) ) {
+ SDL_SetError("Invalid destination blit rectangle");
+ return(-1);
+ }
+ } else {
+ full_dst.x = 0;
+ full_dst.y = 0;
+ full_dst.w = dst->w;
+ full_dst.h = dst->h;
+ dstrect = &full_dst;
+ }
+
+ /* Lock the destination if it's in hardware */
+ dst_locked = 0;
+ if ( SDL_MUSTLOCK(dst) ) {
+ if ( SDL_LockSurface(dst) < 0 ) {
+ SDL_SetError("Unable to lock destination surface");
+ return(-1);
+ }
+ dst_locked = 1;
+ }
+ /* Lock the source if it's in hardware */
+ src_locked = 0;
+ if ( SDL_MUSTLOCK(src) ) {
+ if ( SDL_LockSurface(src) < 0 ) {
+ if ( dst_locked ) {
+ SDL_UnlockSurface(dst);
+ }
+ SDL_SetError("Unable to lock source surface");
+ return(-1);
+ }
+ src_locked = 1;
+ }
+
+ /* Set up the data... */
+ pos = 0x10000;
+ inc = (srcrect->h << 16) / dstrect->h;
+ src_row = srcrect->y;
+ dst_row = dstrect->y;
+
+#ifdef USE_ASM_STRETCH
+ /* Write the opcodes for this stretch */
+ if ( (bpp == 3) ||
+ (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
+ use_asm = SDL_FALSE;
+ }
+#endif
+
+ /* Perform the stretch blit */
+ for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) {
+ dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
+ + (dstrect->x*bpp);
+ while ( pos >= 0x10000L ) {
+ srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
+ + (srcrect->x*bpp);
+ ++src_row;
+ pos -= 0x10000L;
+ }
+#ifdef USE_ASM_STRETCH
+ if (use_asm) {
+#ifdef __GNUC__
+ __asm__ __volatile__ (
+ "call *%4"
+ : "=&D" (u1), "=&S" (u2)
+ : "0" (dstp), "1" (srcp), "r" (copy_row)
+ : "memory" );
+#elif defined(_MSC_VER) || defined(__WATCOMC__)
+ { void *code = copy_row;
+ __asm {
+ push edi
+ push esi
+
+ mov edi, dstp
+ mov esi, srcp
+ call dword ptr code
+
+ pop esi
+ pop edi
+ }
+ }
+#else
+#error Need inline assembly for this compiler
+#endif
+ } else
+#endif
+ switch (bpp) {
+ case 1:
+ copy_row1(srcp, srcrect->w, dstp, dstrect->w);
+ break;
+ case 2:
+ copy_row2((Uint16 *)srcp, srcrect->w,
+ (Uint16 *)dstp, dstrect->w);
+ break;
+ case 3:
+ copy_row3(srcp, srcrect->w, dstp, dstrect->w);
+ break;
+ case 4:
+ copy_row4((Uint32 *)srcp, srcrect->w,
+ (Uint32 *)dstp, dstrect->w);
+ break;
+ }
+ pos += inc;
+ }
+
+ /* We need to unlock the surfaces if they're locked */
+ if ( dst_locked ) {
+ SDL_UnlockSurface(dst);
+ }
+ if ( src_locked ) {
+ SDL_UnlockSurface(src);
+ }
+ return(0);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_stretch_c.h b/distrib/sdl-1.2.15/src/video/SDL_stretch_c.h
new file mode 100644
index 0000000..4cc6acb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_stretch_c.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+extern int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_surface.c b/distrib/sdl-1.2.15/src/video/SDL_surface.c
new file mode 100644
index 0000000..0f3ad12
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_surface.c
@@ -0,0 +1,941 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_cursor_c.h"
+#include "SDL_blit.h"
+#include "SDL_RLEaccel_c.h"
+#include "SDL_pixels_c.h"
+#include "SDL_leaks.h"
+
+
+/* Public routines */
+/*
+ * Create an empty RGB surface of the appropriate depth
+ */
+SDL_Surface * SDL_CreateRGBSurface (Uint32 flags,
+ int width, int height, int depth,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ SDL_Surface *screen;
+ SDL_Surface *surface;
+
+ /* Make sure the size requested doesn't overflow our datatypes */
+ /* Next time I write a library like SDL, I'll use int for size. :) */
+ if ( width >= 16384 || height >= 65536 ) {
+ SDL_SetError("Width or height is too large");
+ return(NULL);
+ }
+
+ /* Check to see if we desire the surface in video memory */
+ if ( video ) {
+ screen = SDL_PublicSurface;
+ } else {
+ screen = NULL;
+ }
+ if ( screen && ((screen->flags&SDL_HWSURFACE) == SDL_HWSURFACE) ) {
+ if ( (flags&(SDL_SRCCOLORKEY|SDL_SRCALPHA)) != 0 ) {
+ flags |= SDL_HWSURFACE;
+ }
+ if ( (flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! current_video->info.blit_hw_CC ) {
+ flags &= ~SDL_HWSURFACE;
+ }
+ }
+ if ( (flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! current_video->info.blit_hw_A ) {
+ flags &= ~SDL_HWSURFACE;
+ }
+ }
+ } else {
+ flags &= ~SDL_HWSURFACE;
+ }
+
+ /* Allocate the surface */
+ surface = (SDL_Surface *)SDL_malloc(sizeof(*surface));
+ if ( surface == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ surface->flags = SDL_SWSURFACE;
+ if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ if ((Amask) && (video->displayformatalphapixel))
+ {
+ depth = video->displayformatalphapixel->BitsPerPixel;
+ Rmask = video->displayformatalphapixel->Rmask;
+ Gmask = video->displayformatalphapixel->Gmask;
+ Bmask = video->displayformatalphapixel->Bmask;
+ Amask = video->displayformatalphapixel->Amask;
+ }
+ else
+ {
+ depth = screen->format->BitsPerPixel;
+ Rmask = screen->format->Rmask;
+ Gmask = screen->format->Gmask;
+ Bmask = screen->format->Bmask;
+ Amask = screen->format->Amask;
+ }
+ }
+ surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
+ if ( surface->format == NULL ) {
+ SDL_free(surface);
+ return(NULL);
+ }
+ if ( Amask ) {
+ surface->flags |= SDL_SRCALPHA;
+ }
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = SDL_CalculatePitch(surface);
+ surface->pixels = NULL;
+ surface->offset = 0;
+ surface->hwdata = NULL;
+ surface->locked = 0;
+ surface->map = NULL;
+ surface->unused1 = 0;
+ SDL_SetClipRect(surface, NULL);
+ SDL_FormatChanged(surface);
+
+ /* Get the pixels */
+ if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) ||
+ (video->AllocHWSurface(this, surface) < 0) ) {
+ if ( surface->w && surface->h ) {
+ surface->pixels = SDL_malloc(surface->h*surface->pitch);
+ if ( surface->pixels == NULL ) {
+ SDL_FreeSurface(surface);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ /* This is important for bitmaps */
+ SDL_memset(surface->pixels, 0, surface->h*surface->pitch);
+ }
+ }
+
+ /* Allocate an empty mapping */
+ surface->map = SDL_AllocBlitMap();
+ if ( surface->map == NULL ) {
+ SDL_FreeSurface(surface);
+ return(NULL);
+ }
+
+ /* The surface is ready to go */
+ surface->refcount = 1;
+#ifdef CHECK_LEAKS
+ ++surfaces_allocated;
+#endif
+ return(surface);
+}
+/*
+ * Create an RGB surface from an existing memory buffer
+ */
+SDL_Surface * SDL_CreateRGBSurfaceFrom (void *pixels,
+ int width, int height, int depth, int pitch,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ SDL_Surface *surface;
+
+ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth,
+ Rmask, Gmask, Bmask, Amask);
+ if ( surface != NULL ) {
+ surface->flags |= SDL_PREALLOC;
+ surface->pixels = pixels;
+ surface->w = width;
+ surface->h = height;
+ surface->pitch = pitch;
+ SDL_SetClipRect(surface, NULL);
+ }
+ return(surface);
+}
+/*
+ * Set the color key in a blittable surface
+ */
+int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key)
+{
+ /* Sanity check the flag as it gets passed in */
+ if ( flag & SDL_SRCCOLORKEY ) {
+ if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) {
+ flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
+ } else {
+ flag = SDL_SRCCOLORKEY;
+ }
+ } else {
+ flag = 0;
+ }
+
+ /* Optimize away operations that don't change anything */
+ if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) &&
+ (key == surface->format->colorkey) ) {
+ return(0);
+ }
+
+ /* UnRLE surfaces before we change the colorkey */
+ if ( surface->flags & SDL_RLEACCEL ) {
+ SDL_UnRLESurface(surface, 1);
+ }
+
+ if ( flag ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+
+ surface->flags |= SDL_SRCCOLORKEY;
+ surface->format->colorkey = key;
+ if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
+ if ( (video->SetHWColorKey == NULL) ||
+ (video->SetHWColorKey(this, surface, key) < 0) ) {
+ surface->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( flag & SDL_RLEACCELOK ) {
+ surface->flags |= SDL_RLEACCELOK;
+ } else {
+ surface->flags &= ~SDL_RLEACCELOK;
+ }
+ } else {
+ surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK);
+ surface->format->colorkey = 0;
+ }
+ SDL_InvalidateMap(surface->map);
+ return(0);
+}
+/* This function sets the alpha channel of a surface */
+int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value)
+{
+ Uint32 oldflags = surface->flags;
+ Uint32 oldalpha = surface->format->alpha;
+
+ /* Sanity check the flag as it gets passed in */
+ if ( flag & SDL_SRCALPHA ) {
+ if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) {
+ flag = (SDL_SRCALPHA | SDL_RLEACCELOK);
+ } else {
+ flag = SDL_SRCALPHA;
+ }
+ } else {
+ flag = 0;
+ }
+
+ /* Optimize away operations that don't change anything */
+ if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) &&
+ (!flag || value == oldalpha) ) {
+ return(0);
+ }
+
+ if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL))
+ SDL_UnRLESurface(surface, 1);
+
+ if ( flag ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ surface->flags |= SDL_SRCALPHA;
+ surface->format->alpha = value;
+ if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
+ if ( (video->SetHWAlpha == NULL) ||
+ (video->SetHWAlpha(this, surface, value) < 0) ) {
+ surface->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( flag & SDL_RLEACCELOK ) {
+ surface->flags |= SDL_RLEACCELOK;
+ } else {
+ surface->flags &= ~SDL_RLEACCELOK;
+ }
+ } else {
+ surface->flags &= ~SDL_SRCALPHA;
+ surface->format->alpha = SDL_ALPHA_OPAQUE;
+ }
+ /*
+ * The representation for software surfaces is independent of
+ * per-surface alpha, so no need to invalidate the blit mapping
+ * if just the alpha value was changed. (If either is 255, we still
+ * need to invalidate.)
+ */
+ if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL
+ || oldflags != surface->flags
+ || (((oldalpha + 1) ^ (value + 1)) & 0x100))
+ SDL_InvalidateMap(surface->map);
+ return(0);
+}
+int SDL_SetAlphaChannel(SDL_Surface *surface, Uint8 value)
+{
+ int row, col;
+ int offset;
+ Uint8 *buf;
+
+ if ( (surface->format->Amask != 0xFF000000) &&
+ (surface->format->Amask != 0x000000FF) ) {
+ SDL_SetError("Unsupported surface alpha mask format");
+ return -1;
+ }
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ if ( surface->format->Amask == 0xFF000000 ) {
+ offset = 3;
+ } else {
+ offset = 0;
+ }
+#else
+ if ( surface->format->Amask == 0xFF000000 ) {
+ offset = 0;
+ } else {
+ offset = 3;
+ }
+#endif /* Byte ordering */
+
+ /* Quickly set the alpha channel of an RGBA or ARGB surface */
+ if ( SDL_MUSTLOCK(surface) ) {
+ if ( SDL_LockSurface(surface) < 0 ) {
+ return -1;
+ }
+ }
+ row = surface->h;
+ while (row--) {
+ col = surface->w;
+ buf = (Uint8 *)surface->pixels + row * surface->pitch + offset;
+ while(col--) {
+ *buf = value;
+ buf += 4;
+ }
+ }
+ if ( SDL_MUSTLOCK(surface) ) {
+ SDL_UnlockSurface(surface);
+ }
+ return 0;
+}
+
+/*
+ * A function to calculate the intersection of two rectangles:
+ * return true if the rectangles intersect, false otherwise
+ */
+static __inline__
+SDL_bool SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *intersection)
+{
+ int Amin, Amax, Bmin, Bmax;
+
+ /* Horizontal intersection */
+ Amin = A->x;
+ Amax = Amin + A->w;
+ Bmin = B->x;
+ Bmax = Bmin + B->w;
+ if(Bmin > Amin)
+ Amin = Bmin;
+ intersection->x = Amin;
+ if(Bmax < Amax)
+ Amax = Bmax;
+ intersection->w = Amax - Amin > 0 ? Amax - Amin : 0;
+
+ /* Vertical intersection */
+ Amin = A->y;
+ Amax = Amin + A->h;
+ Bmin = B->y;
+ Bmax = Bmin + B->h;
+ if(Bmin > Amin)
+ Amin = Bmin;
+ intersection->y = Amin;
+ if(Bmax < Amax)
+ Amax = Bmax;
+ intersection->h = Amax - Amin > 0 ? Amax - Amin : 0;
+
+ return (intersection->w && intersection->h);
+}
+/*
+ * Set the clipping rectangle for a blittable surface
+ */
+SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect)
+{
+ SDL_Rect full_rect;
+
+ /* Don't do anything if there's no surface to act on */
+ if ( ! surface ) {
+ return SDL_FALSE;
+ }
+
+ /* Set up the full surface rectangle */
+ full_rect.x = 0;
+ full_rect.y = 0;
+ full_rect.w = surface->w;
+ full_rect.h = surface->h;
+
+ /* Set the clipping rectangle */
+ if ( ! rect ) {
+ surface->clip_rect = full_rect;
+ return 1;
+ }
+ return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
+}
+void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect)
+{
+ if ( surface && rect ) {
+ *rect = surface->clip_rect;
+ }
+}
+/*
+ * Set up a blit between two surfaces -- split into three parts:
+ * The upper part, SDL_UpperBlit(), performs clipping and rectangle
+ * verification. The lower part is a pointer to a low level
+ * accelerated blitting function.
+ *
+ * These parts are separated out and each used internally by this
+ * library in the optimimum places. They are exported so that if
+ * you know exactly what you are doing, you can optimize your code
+ * by calling the one(s) you need.
+ */
+int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_blit do_blit;
+ SDL_Rect hw_srcrect;
+ SDL_Rect hw_dstrect;
+
+ /* Check to make sure the blit mapping is valid */
+ if ( (src->map->dst != dst) ||
+ (src->map->dst->format_version != src->map->format_version) ) {
+ if ( SDL_MapSurface(src, dst) < 0 ) {
+ return(-1);
+ }
+ }
+
+ /* Figure out which blitter to use */
+ if ( (src->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
+ if ( src == SDL_VideoSurface ) {
+ hw_srcrect = *srcrect;
+ hw_srcrect.x += current_video->offset_x;
+ hw_srcrect.y += current_video->offset_y;
+ srcrect = &hw_srcrect;
+ }
+ if ( dst == SDL_VideoSurface ) {
+ hw_dstrect = *dstrect;
+ hw_dstrect.x += current_video->offset_x;
+ hw_dstrect.y += current_video->offset_y;
+ dstrect = &hw_dstrect;
+ }
+ do_blit = src->map->hw_blit;
+ } else {
+ do_blit = src->map->sw_blit;
+ }
+ return(do_blit(src, srcrect, dst, dstrect));
+}
+
+
+int SDL_UpperBlit (SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_Rect fulldst;
+ int srcx, srcy, w, h;
+
+ /* Make sure the surfaces aren't locked */
+ if ( ! src || ! dst ) {
+ SDL_SetError("SDL_UpperBlit: passed a NULL surface");
+ return(-1);
+ }
+ if ( src->locked || dst->locked ) {
+ SDL_SetError("Surfaces must not be locked during blit");
+ return(-1);
+ }
+
+ /* If the destination rectangle is NULL, use the entire dest surface */
+ if ( dstrect == NULL ) {
+ fulldst.x = fulldst.y = 0;
+ dstrect = &fulldst;
+ }
+
+ /* clip the source rectangle to the source surface */
+ if(srcrect) {
+ int maxw, maxh;
+
+ srcx = srcrect->x;
+ w = srcrect->w;
+ if(srcx < 0) {
+ w += srcx;
+ dstrect->x -= srcx;
+ srcx = 0;
+ }
+ maxw = src->w - srcx;
+ if(maxw < w)
+ w = maxw;
+
+ srcy = srcrect->y;
+ h = srcrect->h;
+ if(srcy < 0) {
+ h += srcy;
+ dstrect->y -= srcy;
+ srcy = 0;
+ }
+ maxh = src->h - srcy;
+ if(maxh < h)
+ h = maxh;
+
+ } else {
+ srcx = srcy = 0;
+ w = src->w;
+ h = src->h;
+ }
+
+ /* clip the destination rectangle against the clip rectangle */
+ {
+ SDL_Rect *clip = &dst->clip_rect;
+ int dx, dy;
+
+ dx = clip->x - dstrect->x;
+ if(dx > 0) {
+ w -= dx;
+ dstrect->x += dx;
+ srcx += dx;
+ }
+ dx = dstrect->x + w - clip->x - clip->w;
+ if(dx > 0)
+ w -= dx;
+
+ dy = clip->y - dstrect->y;
+ if(dy > 0) {
+ h -= dy;
+ dstrect->y += dy;
+ srcy += dy;
+ }
+ dy = dstrect->y + h - clip->y - clip->h;
+ if(dy > 0)
+ h -= dy;
+ }
+
+ if(w > 0 && h > 0) {
+ SDL_Rect sr;
+ sr.x = srcx;
+ sr.y = srcy;
+ sr.w = dstrect->w = w;
+ sr.h = dstrect->h = h;
+ return SDL_LowerBlit(src, &sr, dst, dstrect);
+ }
+ dstrect->w = dstrect->h = 0;
+ return 0;
+}
+
+static int SDL_FillRect1(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
+{
+ /* FIXME: We have to worry about packing order.. *sigh* */
+ SDL_SetError("1-bpp rect fill not yet implemented");
+ return -1;
+}
+
+static int SDL_FillRect4(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
+{
+ /* FIXME: We have to worry about packing order.. *sigh* */
+ SDL_SetError("4-bpp rect fill not yet implemented");
+ return -1;
+}
+
+/*
+ * This function performs a fast fill of the given rectangle with 'color'
+ */
+int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ int x, y;
+ Uint8 *row;
+
+ /* This function doesn't work on surfaces < 8 bpp */
+ if ( dst->format->BitsPerPixel < 8 ) {
+ switch(dst->format->BitsPerPixel) {
+ case 1:
+ return SDL_FillRect1(dst, dstrect, color);
+ break;
+ case 4:
+ return SDL_FillRect4(dst, dstrect, color);
+ break;
+ default:
+ SDL_SetError("Fill rect on unsupported surface format");
+ return(-1);
+ break;
+ }
+ }
+
+ /* If 'dstrect' == NULL, then fill the whole surface */
+ if ( dstrect ) {
+ /* Perform clipping */
+ if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) {
+ return(0);
+ }
+ } else {
+ dstrect = &dst->clip_rect;
+ }
+
+ /* Check for hardware acceleration */
+ if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
+ video->info.blit_fill ) {
+ SDL_Rect hw_rect;
+ if ( dst == SDL_VideoSurface ) {
+ hw_rect = *dstrect;
+ hw_rect.x += current_video->offset_x;
+ hw_rect.y += current_video->offset_y;
+ dstrect = &hw_rect;
+ }
+ return(video->FillHWRect(this, dst, dstrect, color));
+ }
+
+ /* Perform software fill */
+ if ( SDL_LockSurface(dst) != 0 ) {
+ return(-1);
+ }
+ row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+
+ dstrect->x*dst->format->BytesPerPixel;
+ if ( dst->format->palette || (color == 0) ) {
+ x = dstrect->w*dst->format->BytesPerPixel;
+ if ( !color && !((uintptr_t)row&3) && !(x&3) && !(dst->pitch&3) ) {
+ int n = x >> 2;
+ for ( y=dstrect->h; y; --y ) {
+ SDL_memset4(row, 0, n);
+ row += dst->pitch;
+ }
+ } else {
+#ifdef __powerpc__
+ /*
+ * SDL_memset() on PPC (both glibc and codewarrior) uses
+ * the dcbz (Data Cache Block Zero) instruction, which
+ * causes an alignment exception if the destination is
+ * uncachable, so only use it on software surfaces
+ */
+ if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
+ if(dstrect->w >= 8) {
+ /*
+ * 64-bit stores are probably most
+ * efficient to uncached video memory
+ */
+ double fill;
+ SDL_memset(&fill, color, (sizeof fill));
+ for(y = dstrect->h; y; y--) {
+ Uint8 *d = row;
+ unsigned n = x;
+ unsigned nn;
+ Uint8 c = color;
+ double f = fill;
+ while((unsigned long)d
+ & (sizeof(double) - 1)) {
+ *d++ = c;
+ n--;
+ }
+ nn = n / (sizeof(double) * 4);
+ while(nn) {
+ ((double *)d)[0] = f;
+ ((double *)d)[1] = f;
+ ((double *)d)[2] = f;
+ ((double *)d)[3] = f;
+ d += 4*sizeof(double);
+ nn--;
+ }
+ n &= ~(sizeof(double) * 4 - 1);
+ nn = n / sizeof(double);
+ while(nn) {
+ *(double *)d = f;
+ d += sizeof(double);
+ nn--;
+ }
+ n &= ~(sizeof(double) - 1);
+ while(n) {
+ *d++ = c;
+ n--;
+ }
+ row += dst->pitch;
+ }
+ } else {
+ /* narrow boxes */
+ for(y = dstrect->h; y; y--) {
+ Uint8 *d = row;
+ Uint8 c = color;
+ int n = x;
+ while(n) {
+ *d++ = c;
+ n--;
+ }
+ row += dst->pitch;
+ }
+ }
+ } else
+#endif /* __powerpc__ */
+ {
+ for(y = dstrect->h; y; y--) {
+ SDL_memset(row, color, x);
+ row += dst->pitch;
+ }
+ }
+ }
+ } else {
+ switch (dst->format->BytesPerPixel) {
+ case 2:
+ for ( y=dstrect->h; y; --y ) {
+ Uint16 *pixels = (Uint16 *)row;
+ Uint16 c = (Uint16)color;
+ Uint32 cc = (Uint32)c << 16 | c;
+ int n = dstrect->w;
+ if((uintptr_t)pixels & 3) {
+ *pixels++ = c;
+ n--;
+ }
+ if(n >> 1)
+ SDL_memset4(pixels, cc, n >> 1);
+ if(n & 1)
+ pixels[n - 1] = c;
+ row += dst->pitch;
+ }
+ break;
+
+ case 3:
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ color <<= 8;
+ #endif
+ for ( y=dstrect->h; y; --y ) {
+ Uint8 *pixels = row;
+ for ( x=dstrect->w; x; --x ) {
+ SDL_memcpy(pixels, &color, 3);
+ pixels += 3;
+ }
+ row += dst->pitch;
+ }
+ break;
+
+ case 4:
+ for(y = dstrect->h; y; --y) {
+ SDL_memset4(row, color, dstrect->w);
+ row += dst->pitch;
+ }
+ break;
+ }
+ }
+ SDL_UnlockSurface(dst);
+
+ /* We're done! */
+ return(0);
+}
+
+/*
+ * Lock a surface to directly access the pixels
+ */
+int SDL_LockSurface (SDL_Surface *surface)
+{
+ if ( ! surface->locked ) {
+ /* Perform the lock */
+ if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ if ( video->LockHWSurface(this, surface) < 0 ) {
+ return(-1);
+ }
+ }
+ if ( surface->flags & SDL_RLEACCEL ) {
+ SDL_UnRLESurface(surface, 1);
+ surface->flags |= SDL_RLEACCEL; /* save accel'd state */
+ }
+ /* This needs to be done here in case pixels changes value */
+ surface->pixels = (Uint8 *)surface->pixels + surface->offset;
+ }
+
+ /* Increment the surface lock count, for recursive locks */
+ ++surface->locked;
+
+ /* Ready to go.. */
+ return(0);
+}
+/*
+ * Unlock a previously locked surface
+ */
+void SDL_UnlockSurface (SDL_Surface *surface)
+{
+ /* Only perform an unlock if we are locked */
+ if ( ! surface->locked || (--surface->locked > 0) ) {
+ return;
+ }
+
+ /* Perform the unlock */
+ surface->pixels = (Uint8 *)surface->pixels - surface->offset;
+
+ /* Unlock hardware or accelerated surfaces */
+ if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ video->UnlockHWSurface(this, surface);
+ } else {
+ /* Update RLE encoded surface with new data */
+ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ surface->flags &= ~SDL_RLEACCEL; /* stop lying */
+ SDL_RLESurface(surface);
+ }
+ }
+}
+
+/*
+ * Convert a surface into the specified pixel format.
+ */
+SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface,
+ SDL_PixelFormat *format, Uint32 flags)
+{
+ SDL_Surface *convert;
+ Uint32 colorkey = 0;
+ Uint8 alpha = 0;
+ Uint32 surface_flags;
+ SDL_Rect bounds;
+
+ /* Check for empty destination palette! (results in empty image) */
+ if ( format->palette != NULL ) {
+ int i;
+ for ( i=0; i<format->palette->ncolors; ++i ) {
+ if ( (format->palette->colors[i].r != 0) ||
+ (format->palette->colors[i].g != 0) ||
+ (format->palette->colors[i].b != 0) )
+ break;
+ }
+ if ( i == format->palette->ncolors ) {
+ SDL_SetError("Empty destination palette");
+ return(NULL);
+ }
+ }
+
+ /* Only create hw surfaces with alpha channel if hw alpha blits
+ are supported */
+ if(format->Amask != 0 && (flags & SDL_HWSURFACE)) {
+ const SDL_VideoInfo *vi = SDL_GetVideoInfo();
+ if(!vi || !vi->blit_hw_A)
+ flags &= ~SDL_HWSURFACE;
+ }
+
+ /* Create a new surface with the desired format */
+ convert = SDL_CreateRGBSurface(flags,
+ surface->w, surface->h, format->BitsPerPixel,
+ format->Rmask, format->Gmask, format->Bmask, format->Amask);
+ if ( convert == NULL ) {
+ return(NULL);
+ }
+
+ /* Copy the palette if any */
+ if ( format->palette && convert->format->palette ) {
+ SDL_memcpy(convert->format->palette->colors,
+ format->palette->colors,
+ format->palette->ncolors*sizeof(SDL_Color));
+ convert->format->palette->ncolors = format->palette->ncolors;
+ }
+
+ /* Save the original surface color key and alpha */
+ surface_flags = surface->flags;
+ if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ /* Convert colourkeyed surfaces to RGBA if requested */
+ if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY
+ && format->Amask) {
+ surface_flags &= ~SDL_SRCCOLORKEY;
+ } else {
+ colorkey = surface->format->colorkey;
+ SDL_SetColorKey(surface, 0, 0);
+ }
+ }
+ if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ /* Copy over the alpha channel to RGBA if requested */
+ if ( format->Amask ) {
+ surface->flags &= ~SDL_SRCALPHA;
+ } else {
+ alpha = surface->format->alpha;
+ SDL_SetAlpha(surface, 0, 0);
+ }
+ }
+
+ /* Copy over the image data */
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = surface->w;
+ bounds.h = surface->h;
+ SDL_LowerBlit(surface, &bounds, convert, &bounds);
+
+ /* Clean up the original surface, and update converted surface */
+ if ( convert != NULL ) {
+ SDL_SetClipRect(convert, &surface->clip_rect);
+ }
+ if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK);
+ if ( convert != NULL ) {
+ Uint8 keyR, keyG, keyB;
+
+ SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB);
+ SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK),
+ SDL_MapRGB(convert->format, keyR, keyG, keyB));
+ }
+ SDL_SetColorKey(surface, cflags, colorkey);
+ }
+ if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+ if ( convert != NULL ) {
+ SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK),
+ alpha);
+ }
+ if ( format->Amask ) {
+ surface->flags |= SDL_SRCALPHA;
+ } else {
+ SDL_SetAlpha(surface, aflags, alpha);
+ }
+ }
+
+ /* We're ready to go! */
+ return(convert);
+}
+
+/*
+ * Free a surface created by the above function.
+ */
+void SDL_FreeSurface (SDL_Surface *surface)
+{
+ /* Free anything that's not NULL, and not the screen surface */
+ if ((surface == NULL) ||
+ (current_video &&
+ ((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) {
+ return;
+ }
+ if ( --surface->refcount > 0 ) {
+ return;
+ }
+ while ( surface->locked > 0 ) {
+ SDL_UnlockSurface(surface);
+ }
+ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
+ SDL_UnRLESurface(surface, 0);
+ }
+ if ( surface->format ) {
+ SDL_FreeFormat(surface->format);
+ surface->format = NULL;
+ }
+ if ( surface->map != NULL ) {
+ SDL_FreeBlitMap(surface->map);
+ surface->map = NULL;
+ }
+ if ( surface->hwdata ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ video->FreeHWSurface(this, surface);
+ }
+ if ( surface->pixels &&
+ ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) {
+ SDL_free(surface->pixels);
+ }
+ SDL_free(surface);
+#ifdef CHECK_LEAKS
+ --surfaces_allocated;
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h b/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h
new file mode 100644
index 0000000..65287b4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h
@@ -0,0 +1,439 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_sysvideo_h
+#define _SDL_sysvideo_h
+
+#include "SDL_mouse.h"
+#define SDL_PROTOTYPES_ONLY
+#include "SDL_syswm.h"
+#undef SDL_PROTOTYPES_ONLY
+
+/* This file prototypes the video driver implementation.
+ This is designed to be easily converted to C++ in the future.
+ */
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif /* SDL_VIDEO_OPENGL */
+
+/* The SDL video driver */
+typedef struct SDL_VideoDevice SDL_VideoDevice;
+
+/* Define the SDL video driver structure */
+#define _THIS SDL_VideoDevice *_this
+#ifndef _STATUS
+#define _STATUS SDL_status *status
+#endif
+struct SDL_VideoDevice {
+ /* * * */
+ /* The name of this video driver */
+ const char *name;
+
+ /* * * */
+ /* Initialization/Query functions */
+
+ /* Initialize the native video subsystem, filling 'vformat' with the
+ "best" display pixel format, returning 0 or -1 if there's an error.
+ */
+ int (*VideoInit)(_THIS, SDL_PixelFormat *vformat);
+
+ /* List the available video modes for the given pixel format, sorted
+ from largest to smallest.
+ */
+ SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags);
+
+ /* 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.
+ */
+ SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags);
+
+ /* Toggle the fullscreen mode */
+ int (*ToggleFullScreen)(_THIS, int on);
+
+ /* 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.
+ */
+ void (*UpdateMouse)(_THIS);
+
+ /* Create a YUV video surface (possibly overlay) of the given
+ format. The hardware should be able to perform at least 2x
+ scaling on display.
+ */
+ SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height,
+ Uint32 format, SDL_Surface *display);
+
+ /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) }
+ of the physical palette to those in 'colors'. If the device is
+ using a software palette (SDL_HWPALETTE not set), then the
+ changes are reflected in the logical palette of the screen
+ as well.
+ The return value is 1 if all entries could be set properly
+ or 0 otherwise.
+ */
+ int (*SetColors)(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+
+ /* This pointer should exist in the native video subsystem and should
+ point to an appropriate update function for the current video mode
+ */
+ void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects);
+
+ /* Reverse the effects VideoInit() -- called if VideoInit() fails
+ or if the application is shutting down the video subsystem.
+ */
+ void (*VideoQuit)(_THIS);
+
+ /* * * */
+ /* Hardware acceleration functions */
+
+ /* Information about the video hardware */
+ SDL_VideoInfo info;
+
+ /* The pixel format used when SDL_CreateRGBSurface creates SDL_HWSURFACEs with alpha */
+ SDL_PixelFormat* displayformatalphapixel;
+
+ /* Allocates a surface in video memory */
+ int (*AllocHWSurface)(_THIS, SDL_Surface *surface);
+
+ /* Sets the hardware accelerated blit function, if any, based
+ on the current flags of the surface (colorkey, alpha, etc.)
+ */
+ int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst);
+
+ /* Fills a surface rectangle with the given color */
+ int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
+
+ /* Sets video mem colorkey and accelerated blit function */
+ int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key);
+
+ /* Sets per surface hardware alpha value */
+ int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value);
+
+ /* Returns a readable/writable surface */
+ int (*LockHWSurface)(_THIS, SDL_Surface *surface);
+ void (*UnlockHWSurface)(_THIS, SDL_Surface *surface);
+
+ /* Performs hardware flipping */
+ int (*FlipHWSurface)(_THIS, SDL_Surface *surface);
+
+ /* Frees a previously allocated video surface */
+ void (*FreeHWSurface)(_THIS, SDL_Surface *surface);
+
+ /* * * */
+ /* Gamma support */
+
+ Uint16 *gamma;
+
+ /* Set the gamma correction directly (emulated with gamma ramps) */
+ int (*SetGamma)(_THIS, float red, float green, float blue);
+
+ /* Get the gamma correction directly (emulated with gamma ramps) */
+ int (*GetGamma)(_THIS, float *red, float *green, float *blue);
+
+ /* Set the gamma ramp */
+ int (*SetGammaRamp)(_THIS, Uint16 *ramp);
+
+ /* Get the gamma ramp */
+ int (*GetGammaRamp)(_THIS, Uint16 *ramp);
+
+ /* * * */
+ /* OpenGL support */
+
+ /* Sets the dll to use for OpenGL and loads it */
+ int (*GL_LoadLibrary)(_THIS, const char *path);
+
+ /* Retrieves the address of a function in the gl library */
+ void* (*GL_GetProcAddress)(_THIS, const char *proc);
+
+ /* Get attribute information from the windowing system. */
+ int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int* value);
+
+ /* Make the context associated with this driver current */
+ int (*GL_MakeCurrent)(_THIS);
+
+ /* Swap the current buffers in double buffer mode. */
+ void (*GL_SwapBuffers)(_THIS);
+
+ /* OpenGL functions for SDL_OPENGLBLIT */
+#if SDL_VIDEO_OPENGL
+#if !defined(__WIN32__)
+#define WINAPI
+#endif
+#define SDL_PROC(ret,func,params) ret (WINAPI *func) params;
+#include "SDL_glfuncs.h"
+#undef SDL_PROC
+
+ /* Texture id */
+ GLuint texture;
+#endif
+ int is_32bit;
+
+ /* * * */
+ /* Window manager functions */
+
+ /* Set the title and icon text */
+ void (*SetCaption)(_THIS, const char *title, const char *icon);
+
+ /* Set the window icon image */
+ void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask);
+
+ /* Iconify the window.
+ This function returns 1 if there is a window manager and the
+ window was actually iconified, it returns 0 otherwise.
+ */
+ int (*IconifyWindow)(_THIS);
+
+ /* Grab or ungrab keyboard and mouse input */
+ SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode);
+
+ /* Get some platform dependent window information */
+ int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info);
+
+ /* set window position */
+ void (*SetWindowPos)(_THIS, int x, int y);
+
+ /* get window position */
+ void (*GetWindowPos)(_THIS, int *px, int *py);
+
+ /* determine if the window is fully visible on screen */
+ int (*IsWindowVisible)(_THIS, int recenter);
+
+ /* get main monitor's resolution */
+ int (*GetMonitorDPI)(_THIS, int *xdpi, int *ydpi);
+
+ /* get nearest monitor's rectangle */
+ int (*GetMonitorRect)(_THIS, SDL_Rect* rect);
+
+ /* * * */
+ /* Cursor manager functions */
+
+ /* Free a window manager cursor
+ This function can be NULL if CreateWMCursor is also NULL.
+ */
+ void (*FreeWMCursor)(_THIS, WMcursor *cursor);
+
+ /* If not NULL, create a black/white window manager cursor */
+ WMcursor *(*CreateWMCursor)(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+
+ /* Show the specified cursor, or hide if cursor is NULL */
+ int (*ShowWMCursor)(_THIS, WMcursor *cursor);
+
+ /* Warp the window manager cursor to (x,y)
+ If NULL, a mouse motion event is posted internally.
+ */
+ void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y);
+
+ /* If not NULL, this is called when a mouse motion event occurs */
+ void (*MoveWMCursor)(_THIS, int x, int y);
+
+ /* 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 (*CheckMouseMode)(_THIS);
+
+ /* * * */
+ /* Event manager functions */
+
+ /* Initialize keyboard mapping for this driver */
+ void (*InitOSKeymap)(_THIS);
+
+ /* Handle any queued OS events */
+ void (*PumpEvents)(_THIS);
+
+ /* * * */
+ /* Data common to all drivers */
+ SDL_Surface *screen;
+ SDL_Surface *shadow;
+ SDL_Surface *visible;
+ SDL_Palette *physpal; /* physical palette, if != logical palette */
+ SDL_Color *gammacols; /* gamma-corrected colours, or NULL */
+ char *wm_title;
+ char *wm_icon;
+ int offset_x;
+ int offset_y;
+ SDL_GrabMode input_grab;
+
+ /* Driver information flags */
+ int handles_any_size; /* Driver handles any size video mode */
+
+ /* * * */
+ /* Data used by the GL drivers */
+ struct {
+ int red_size;
+ int green_size;
+ int blue_size;
+ int alpha_size;
+ int depth_size;
+ int buffer_size;
+ int stencil_size;
+ int double_buffer;
+ int accum_red_size;
+ int accum_green_size;
+ int accum_blue_size;
+ int accum_alpha_size;
+ int stereo;
+ int multisamplebuffers;
+ int multisamplesamples;
+ int accelerated;
+ int swap_control;
+ int driver_loaded;
+ char driver_path[256];
+ void* dll_handle;
+ } gl_config;
+
+ /* * * */
+ /* Data private to this driver */
+ struct SDL_PrivateVideoData *hidden;
+ struct SDL_PrivateGLData *gl_data;
+
+ /* * * */
+ /* The function used to dispose of this structure */
+ void (*free)(_THIS);
+};
+#undef _THIS
+
+typedef struct VideoBootStrap {
+ const char *name;
+ const char *desc;
+ int (*available)(void);
+ SDL_VideoDevice *(*create)(int devindex);
+} VideoBootStrap;
+
+#if SDL_VIDEO_DRIVER_QUARTZ
+extern VideoBootStrap QZ_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_X11
+extern VideoBootStrap X11_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DGA
+extern VideoBootStrap DGA_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_NANOX
+extern VideoBootStrap NX_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_IPOD
+extern VideoBootStrap iPod_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_QTOPIA
+extern VideoBootStrap Qtopia_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_WSCONS
+extern VideoBootStrap WSCONS_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_FBCON
+extern VideoBootStrap FBCON_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DIRECTFB
+extern VideoBootStrap DirectFB_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_PS2GS
+extern VideoBootStrap PS2GS_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_PS3
+extern VideoBootStrap PS3_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_GGI
+extern VideoBootStrap GGI_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_VGL
+extern VideoBootStrap VGL_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_SVGALIB
+extern VideoBootStrap SVGALIB_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_GAPI
+extern VideoBootStrap GAPI_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_WINDIB
+extern VideoBootStrap WINDIB_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DDRAW
+extern VideoBootStrap DIRECTX_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_BWINDOW
+extern VideoBootStrap BWINDOW_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_TOOLBOX
+extern VideoBootStrap TOOLBOX_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DRAWSPROCKET
+extern VideoBootStrap DSp_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_PHOTON
+extern VideoBootStrap ph_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_EPOC
+extern VideoBootStrap EPOC_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_XBIOS
+extern VideoBootStrap XBIOS_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_GEM
+extern VideoBootStrap GEM_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_PICOGUI
+extern VideoBootStrap PG_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DC
+extern VideoBootStrap DC_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_NDS
+extern VideoBootStrap NDS_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_RISCOS
+extern VideoBootStrap RISCOS_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_OS2FS
+extern VideoBootStrap OS2FSLib_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_AALIB
+extern VideoBootStrap AALIB_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_CACA
+extern VideoBootStrap CACA_bootstrap;
+#endif
+#if SDL_VIDEO_DRIVER_DUMMY
+extern VideoBootStrap DUMMY_bootstrap;
+#endif
+
+/* This is the current video device */
+extern SDL_VideoDevice *current_video;
+
+#define SDL_VideoSurface (current_video->screen)
+#define SDL_ShadowSurface (current_video->shadow)
+#define SDL_PublicSurface (current_video->visible)
+
+#endif /* _SDL_sysvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/SDL_video.c b/distrib/sdl-1.2.15/src/video/SDL_video.c
new file mode 100644
index 0000000..f4f4407
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_video.c
@@ -0,0 +1,2041 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* The high-level video driver subsystem */
+
+#include "SDL.h"
+#include "SDL_sysvideo.h"
+#include "SDL_blit.h"
+#include "SDL_pixels_c.h"
+#include "SDL_cursor_c.h"
+#include "../events/SDL_sysevents.h"
+#include "../events/SDL_events_c.h"
+
+/* Available video drivers */
+static VideoBootStrap *bootstrap[] = {
+#if SDL_VIDEO_DRIVER_QUARTZ
+ &QZ_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_X11
+ &X11_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DGA
+ &DGA_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_NANOX
+ &NX_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_IPOD
+ &iPod_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_QTOPIA
+ &Qtopia_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_WSCONS
+ &WSCONS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_FBCON
+ &FBCON_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DIRECTFB
+ &DirectFB_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PS2GS
+ &PS2GS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PS3
+ &PS3_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_GGI
+ &GGI_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_VGL
+ &VGL_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_SVGALIB
+ &SVGALIB_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_GAPI
+ &GAPI_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_WINDIB
+ &WINDIB_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DDRAW
+ &DIRECTX_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_BWINDOW
+ &BWINDOW_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_TOOLBOX
+ &TOOLBOX_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DRAWSPROCKET
+ &DSp_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PHOTON
+ &ph_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_EPOC
+ &EPOC_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_XBIOS
+ &XBIOS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_GEM
+ &GEM_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_PICOGUI
+ &PG_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DC
+ &DC_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_NDS
+ &NDS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_RISCOS
+ &RISCOS_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_OS2FS
+ &OS2FSLib_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_AALIB
+ &AALIB_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_CACA
+ &CACA_bootstrap,
+#endif
+#if SDL_VIDEO_DRIVER_DUMMY
+ &DUMMY_bootstrap,
+#endif
+ NULL
+};
+
+SDL_VideoDevice *current_video = NULL;
+
+/* Various local functions */
+int SDL_VideoInit(const char *driver_name, Uint32 flags);
+void SDL_VideoQuit(void);
+void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects);
+
+static SDL_GrabMode SDL_WM_GrabInputOff(void);
+#if SDL_VIDEO_OPENGL
+static int lock_count = 0;
+#endif
+
+
+/*
+ * Initialize the video and event subsystems -- determine native pixel format
+ */
+int SDL_VideoInit (const char *driver_name, Uint32 flags)
+{
+ SDL_VideoDevice *video;
+ int index;
+ int i;
+ SDL_PixelFormat vformat;
+ Uint32 video_flags;
+
+ /* Toggle the event thread flags, based on OS requirements */
+#if defined(MUST_THREAD_EVENTS)
+ flags |= SDL_INIT_EVENTTHREAD;
+#elif defined(CANT_THREAD_EVENTS)
+ if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) {
+ SDL_SetError("OS doesn't support threaded events");
+ return(-1);
+ }
+#endif
+
+ /* Check to make sure we don't overwrite 'current_video' */
+ if ( current_video != NULL ) {
+ SDL_VideoQuit();
+ }
+
+ /* Select the proper video driver */
+ index = 0;
+ video = NULL;
+ if ( driver_name != NULL ) {
+#if 0 /* This will be replaced with a better driver selection API */
+ if ( SDL_strrchr(driver_name, ':') != NULL ) {
+ index = atoi(SDL_strrchr(driver_name, ':')+1);
+ }
+#endif
+ for ( i=0; bootstrap[i]; ++i ) {
+ if ( SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
+ if ( bootstrap[i]->available() ) {
+ video = bootstrap[i]->create(index);
+ break;
+ }
+ }
+ }
+ } else {
+ for ( i=0; bootstrap[i]; ++i ) {
+ if ( bootstrap[i]->available() ) {
+ video = bootstrap[i]->create(index);
+ if ( video != NULL ) {
+ break;
+ }
+ }
+ }
+ }
+ if ( video == NULL ) {
+ SDL_SetError("No available video device");
+ return(-1);
+ }
+ current_video = video;
+ current_video->name = bootstrap[i]->name;
+
+ /* Do some basic variable initialization */
+ video->screen = NULL;
+ video->shadow = NULL;
+ video->visible = NULL;
+ video->physpal = NULL;
+ video->gammacols = NULL;
+ video->gamma = NULL;
+ video->wm_title = NULL;
+ video->wm_icon = NULL;
+ video->offset_x = 0;
+ video->offset_y = 0;
+ SDL_memset(&video->info, 0, (sizeof video->info));
+
+ video->displayformatalphapixel = NULL;
+
+ /* Set some very sane GL defaults */
+ video->gl_config.driver_loaded = 0;
+ video->gl_config.dll_handle = NULL;
+ video->gl_config.red_size = 3;
+ video->gl_config.green_size = 3;
+ video->gl_config.blue_size = 2;
+ video->gl_config.alpha_size = 0;
+ video->gl_config.buffer_size = 0;
+ video->gl_config.depth_size = 16;
+ video->gl_config.stencil_size = 0;
+ video->gl_config.double_buffer = 1;
+ video->gl_config.accum_red_size = 0;
+ video->gl_config.accum_green_size = 0;
+ video->gl_config.accum_blue_size = 0;
+ video->gl_config.accum_alpha_size = 0;
+ video->gl_config.stereo = 0;
+ video->gl_config.multisamplebuffers = 0;
+ video->gl_config.multisamplesamples = 0;
+ video->gl_config.accelerated = -1; /* not known, don't set */
+ video->gl_config.swap_control = -1; /* not known, don't set */
+
+ /* Initialize the video subsystem */
+ SDL_memset(&vformat, 0, sizeof(vformat));
+ if ( video->VideoInit(video, &vformat) < 0 ) {
+ SDL_VideoQuit();
+ return(-1);
+ }
+
+ /* Create a zero sized video surface of the appropriate format */
+ video_flags = SDL_SWSURFACE;
+ SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0,
+ vformat.BitsPerPixel,
+ vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);
+ if ( SDL_VideoSurface == NULL ) {
+ SDL_VideoQuit();
+ return(-1);
+ }
+ SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */
+
+#if 0 /* Don't change the current palette - may be used by other programs.
+ * The application can't do anything with the display surface until
+ * a video mode has been set anyway. :)
+ */
+ /* If we have a palettized surface, create a default palette */
+ if ( SDL_VideoSurface->format->palette ) {
+ SDL_PixelFormat *vf = SDL_VideoSurface->format;
+ SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
+ video->SetColors(video,
+ 0, vf->palette->ncolors, vf->palette->colors);
+ }
+#endif
+ video->info.vfmt = SDL_VideoSurface->format;
+
+ /* Start the event loop */
+ if ( SDL_StartEventLoop(flags) < 0 ) {
+ SDL_VideoQuit();
+ return(-1);
+ }
+ SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD);
+
+ /* We're ready to go! */
+ return(0);
+}
+
+char *SDL_VideoDriverName(char *namebuf, int maxlen)
+{
+ if ( current_video != NULL ) {
+ SDL_strlcpy(namebuf, current_video->name, maxlen);
+ return(namebuf);
+ }
+ return(NULL);
+}
+
+/*
+ * Get the current display surface
+ */
+SDL_Surface *SDL_GetVideoSurface(void)
+{
+ SDL_Surface *visible;
+
+ visible = NULL;
+ if ( current_video ) {
+ visible = current_video->visible;
+ }
+ return(visible);
+}
+
+/*
+ * Get the current information about the video hardware
+ */
+const SDL_VideoInfo *SDL_GetVideoInfo(void)
+{
+ const SDL_VideoInfo *info;
+
+ info = NULL;
+ if ( current_video ) {
+ info = &current_video->info;
+ }
+ return(info);
+}
+
+/*
+ * Return a pointer to an array of available screen dimensions for the
+ * given format, sorted largest to smallest. Returns NULL if there are
+ * no dimensions available for a particular format, or (SDL_Rect **)-1
+ * if any dimension is okay for the given format. If 'format' is NULL,
+ * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt
+ */
+SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ SDL_Rect **modes;
+
+ modes = NULL;
+ if ( SDL_VideoSurface ) {
+ if ( format == NULL ) {
+ format = SDL_VideoSurface->format;
+ }
+ modes = video->ListModes(this, format, flags);
+ }
+ return(modes);
+}
+
+/*
+ * Check to see if a particular video mode is supported.
+ * It returns 0 if the requested mode is not supported under any bit depth,
+ * or returns the bits-per-pixel of the closest available mode with the
+ * given width and height. If this bits-per-pixel is different from the
+ * one used when setting the video mode, SDL_SetVideoMode() will succeed,
+ * but will emulate the requested bits-per-pixel with a shadow surface.
+ */
+static Uint8 SDL_closest_depths[4][8] = {
+ /* 8 bit closest depth ordering */
+ { 0, 8, 16, 15, 32, 24, 0, 0 },
+ /* 15,16 bit closest depth ordering */
+ { 0, 16, 15, 32, 24, 8, 0, 0 },
+ /* 24 bit closest depth ordering */
+ { 0, 24, 32, 16, 15, 8, 0, 0 },
+ /* 32 bit closest depth ordering */
+ { 0, 32, 16, 15, 24, 8, 0, 0 }
+};
+
+
+#ifdef __MACOS__ /* MPW optimization bug? */
+#define NEGATIVE_ONE 0xFFFFFFFF
+#else
+#define NEGATIVE_ONE -1
+#endif
+
+int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags)
+{
+ int table, b, i;
+ int supported;
+ SDL_PixelFormat format;
+ SDL_Rect **sizes;
+
+ /* Currently 1 and 4 bpp are not supported */
+ if ( bpp < 8 || bpp > 32 ) {
+ return(0);
+ }
+ if ( (width <= 0) || (height <= 0) ) {
+ return(0);
+ }
+
+ /* Search through the list valid of modes */
+ SDL_memset(&format, 0, sizeof(format));
+ supported = 0;
+ table = ((bpp+7)/8)-1;
+ SDL_closest_depths[table][0] = bpp;
+ SDL_closest_depths[table][7] = 0;
+ for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
+ format.BitsPerPixel = SDL_closest_depths[table][b];
+ sizes = SDL_ListModes(&format, flags);
+ if ( sizes == (SDL_Rect **)0 ) {
+ /* No sizes supported at this bit-depth */
+ continue;
+ } else
+ if (sizes == (SDL_Rect **)NEGATIVE_ONE) {
+ /* Any size supported at this bit-depth */
+ supported = 1;
+ continue;
+ } else if (current_video->handles_any_size) {
+ /* Driver can center a smaller surface to simulate fullscreen */
+ for ( i=0; sizes[i]; ++i ) {
+ if ((sizes[i]->w >= width) && (sizes[i]->h >= height)) {
+ supported = 1; /* this mode can fit the centered window. */
+ break;
+ }
+ }
+ } else
+ for ( i=0; sizes[i]; ++i ) {
+ if ((sizes[i]->w == width) && (sizes[i]->h == height)) {
+ supported = 1;
+ break;
+ }
+ }
+ }
+ if ( supported ) {
+ --b;
+ return(SDL_closest_depths[table][b]);
+ } else {
+ return(0);
+ }
+}
+
+/*
+ * Get the closest non-emulated video mode to the one requested
+ */
+static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags)
+{
+ int table, b, i;
+ int supported;
+ int native_bpp;
+ SDL_PixelFormat format;
+ SDL_Rect **sizes;
+
+ /* Check parameters */
+ if ( *BitsPerPixel < 8 || *BitsPerPixel > 32 ) {
+ SDL_SetError("Invalid bits per pixel (range is {8...32})");
+ return(0);
+ }
+ if ((*w <= 0) || (*h <= 0)) {
+ SDL_SetError("Invalid width or height");
+ return(0);
+ }
+
+ /* Try the original video mode, get the closest depth */
+ native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags);
+ if ( native_bpp == *BitsPerPixel ) {
+ return(1);
+ }
+ if ( native_bpp > 0 ) {
+ *BitsPerPixel = native_bpp;
+ return(1);
+ }
+
+ /* No exact size match at any depth, look for closest match */
+ SDL_memset(&format, 0, sizeof(format));
+ supported = 0;
+ table = ((*BitsPerPixel+7)/8)-1;
+ SDL_closest_depths[table][0] = *BitsPerPixel;
+ SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel;
+ for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
+ int best;
+
+ format.BitsPerPixel = SDL_closest_depths[table][b];
+ sizes = SDL_ListModes(&format, flags);
+ if ( sizes == (SDL_Rect **)0 ) {
+ /* No sizes supported at this bit-depth */
+ continue;
+ }
+ best=0;
+ for ( i=0; sizes[i]; ++i ) {
+ /* Mode with both dimensions bigger or equal than asked ? */
+ if ((sizes[i]->w >= *w) && (sizes[i]->h >= *h)) {
+ /* Mode with any dimension smaller or equal than current best ? */
+ if ((sizes[i]->w <= sizes[best]->w) || (sizes[i]->h <= sizes[best]->h)) {
+ /* Now choose the mode that has less pixels */
+ if ((sizes[i]->w * sizes[i]->h) <= (sizes[best]->w * sizes[best]->h)) {
+ best=i;
+ supported = 1;
+ }
+ }
+ }
+ }
+ if (supported) {
+ *w=sizes[best]->w;
+ *h=sizes[best]->h;
+ *BitsPerPixel = SDL_closest_depths[table][b];
+ }
+ }
+ if ( ! supported ) {
+ SDL_SetError("No video mode large enough for %dx%d", *w, *h);
+ }
+ return(supported);
+}
+
+/* This should probably go somewhere else -- like SDL_surface.c */
+static void SDL_ClearSurface(SDL_Surface *surface)
+{
+ Uint32 black;
+
+ black = SDL_MapRGB(surface->format, 0, 0, 0);
+ SDL_FillRect(surface, NULL, black);
+ if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) {
+ SDL_Flip(surface);
+ SDL_FillRect(surface, NULL, black);
+ }
+ if (surface->flags&SDL_FULLSCREEN) {
+ SDL_Flip(surface);
+ }
+}
+
+/*
+ * Create a shadow surface suitable for fooling the app. :-)
+ */
+static void SDL_CreateShadowSurface(int depth)
+{
+ Uint32 Rmask, Gmask, Bmask;
+
+ /* Allocate the shadow surface */
+ if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
+ Rmask = (SDL_VideoSurface->format)->Rmask;
+ Gmask = (SDL_VideoSurface->format)->Gmask;
+ Bmask = (SDL_VideoSurface->format)->Bmask;
+ } else {
+ Rmask = Gmask = Bmask = 0;
+ }
+ SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ SDL_VideoSurface->w, SDL_VideoSurface->h,
+ depth, Rmask, Gmask, Bmask, 0);
+ if ( SDL_ShadowSurface == NULL ) {
+ return;
+ }
+
+ /* 8-bit shadow surfaces report that they have exclusive palette */
+ if ( SDL_ShadowSurface->format->palette ) {
+ SDL_ShadowSurface->flags |= SDL_HWPALETTE;
+ if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {
+ SDL_memcpy(SDL_ShadowSurface->format->palette->colors,
+ SDL_VideoSurface->format->palette->colors,
+ SDL_VideoSurface->format->palette->ncolors*
+ sizeof(SDL_Color));
+ } else {
+ SDL_DitherColors(
+ SDL_ShadowSurface->format->palette->colors, depth);
+ }
+ }
+
+ /* If the video surface is resizable, the shadow should say so */
+ if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) {
+ SDL_ShadowSurface->flags |= SDL_RESIZABLE;
+ }
+ /* If the video surface has no frame, the shadow should say so */
+ if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) {
+ SDL_ShadowSurface->flags |= SDL_NOFRAME;
+ }
+ /* If the video surface is fullscreen, the shadow should say so */
+ if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ SDL_ShadowSurface->flags |= SDL_FULLSCREEN;
+ }
+ /* If the video surface is flippable, the shadow should say so */
+ if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ SDL_ShadowSurface->flags |= SDL_DOUBLEBUF;
+ }
+ return;
+}
+
+#ifdef __QNXNTO__
+ #include <sys/neutrino.h>
+#endif /* __QNXNTO__ */
+
+#ifdef WIN32
+ extern int sysevents_mouse_pressed;
+#endif
+
+/*
+ * Set the requested video mode, allocating a shadow buffer if necessary.
+ */
+SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)
+{
+ SDL_VideoDevice *video, *this;
+ SDL_Surface *prev_mode, *mode;
+ int video_w;
+ int video_h;
+ int video_bpp;
+ int is_opengl;
+ SDL_GrabMode saved_grab;
+
+ #ifdef WIN32
+ sysevents_mouse_pressed = 0;
+ #endif
+
+ /* Start up the video driver, if necessary..
+ WARNING: This is the only function protected this way!
+ */
+ if ( ! current_video ) {
+ if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
+ return(NULL);
+ }
+ }
+ this = video = current_video;
+
+ /* Default to the current width and height */
+ if ( width == 0 ) {
+ width = video->info.current_w;
+ }
+ if ( height == 0 ) {
+ height = video->info.current_h;
+ }
+ /* Default to the current video bpp */
+ if ( bpp == 0 ) {
+ flags |= SDL_ANYFORMAT;
+ bpp = SDL_VideoSurface->format->BitsPerPixel;
+ }
+
+ /* Get a good video mode, the closest one possible */
+ video_w = width;
+ video_h = height;
+ video_bpp = bpp;
+ if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {
+ return(NULL);
+ }
+
+ /* Check the requested flags */
+ /* There's no palette in > 8 bits-per-pixel mode */
+ if ( video_bpp > 8 ) {
+ flags &= ~SDL_HWPALETTE;
+ }
+#if 0
+ if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
+ /* There's no windowed double-buffering */
+ flags &= ~SDL_DOUBLEBUF;
+ }
+#endif
+ if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ /* Use hardware surfaces when double-buffering */
+ flags |= SDL_HWSURFACE;
+ }
+
+ is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL );
+ if ( is_opengl ) {
+ /* These flags are for 2D video modes only */
+ flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF);
+ }
+
+ /* Reset the keyboard here so event callbacks can run */
+ SDL_ResetKeyboard();
+ SDL_ResetMouse();
+ SDL_SetMouseRange(width, height);
+ SDL_cursorstate &= ~CURSOR_USINGSW;
+
+ /* Clean up any previous video mode */
+ if ( SDL_PublicSurface != NULL ) {
+ SDL_PublicSurface = NULL;
+ }
+ if ( SDL_ShadowSurface != NULL ) {
+ SDL_Surface *ready_to_go;
+ ready_to_go = SDL_ShadowSurface;
+ SDL_ShadowSurface = NULL;
+ SDL_FreeSurface(ready_to_go);
+ }
+ if ( video->physpal ) {
+ SDL_free(video->physpal->colors);
+ SDL_free(video->physpal);
+ video->physpal = NULL;
+ }
+ if( video->gammacols) {
+ SDL_free(video->gammacols);
+ video->gammacols = NULL;
+ }
+
+ /* Save the previous grab state and turn off grab for mode switch */
+ saved_grab = SDL_WM_GrabInputOff();
+
+ /* Try to set the video mode, along with offset and clipping */
+ prev_mode = SDL_VideoSurface;
+ SDL_LockCursor();
+ SDL_VideoSurface = NULL; /* In case it's freed by driver */
+ mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);
+ if ( mode ) { /* Prevent resize events from mode change */
+ /* But not on OS/2 */
+#ifndef __OS2__
+ SDL_PrivateResize(mode->w, mode->h);
+#endif
+
+ /* Sam - If we asked for OpenGL mode, and didn't get it, fail */
+ if ( is_opengl && !(mode->flags & SDL_OPENGL) ) {
+ mode = NULL;
+ SDL_SetError("OpenGL not available");
+ }
+ }
+ /*
+ * rcg11292000
+ * If you try to set an SDL_OPENGL surface, and fail to find a
+ * matching visual, then the next call to SDL_SetVideoMode()
+ * will segfault, since we no longer point to a dummy surface,
+ * but rather NULL.
+ * Sam 11/29/00
+ * WARNING, we need to make sure that the previous mode hasn't
+ * already been freed by the video driver. What do we do in
+ * that case? Should we call SDL_VideoInit() again?
+ */
+ SDL_VideoSurface = (mode != NULL) ? mode : prev_mode;
+
+ if ( (mode != NULL) && (!is_opengl) ) {
+ /* Sanity check */
+ if ( (mode->w < width) || (mode->h < height) ) {
+ SDL_SetError("Video mode smaller than requested");
+ return(NULL);
+ }
+
+ /* If we have a palettized surface, create a default palette */
+ if ( mode->format->palette ) {
+ SDL_PixelFormat *vf = mode->format;
+ SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
+ video->SetColors(this, 0, vf->palette->ncolors,
+ vf->palette->colors);
+ }
+
+ /* Clear the surface to black */
+ video->offset_x = 0;
+ video->offset_y = 0;
+ mode->offset = 0;
+ SDL_SetClipRect(mode, NULL);
+ SDL_ClearSurface(mode);
+
+ /* Now adjust the offsets to match the desired mode */
+ video->offset_x = (mode->w-width)/2;
+ video->offset_y = (mode->h-height)/2;
+ mode->offset = video->offset_y*mode->pitch +
+ video->offset_x*mode->format->BytesPerPixel;
+#ifdef DEBUG_VIDEO
+ fprintf(stderr,
+ "Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n",
+ width, height, bpp,
+ mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);
+#endif
+ mode->w = width;
+ mode->h = height;
+ SDL_SetClipRect(mode, NULL);
+ }
+ SDL_ResetCursor();
+ SDL_UnlockCursor();
+
+ /* If we failed setting a video mode, return NULL... (Uh Oh!) */
+ if ( mode == NULL ) {
+ return(NULL);
+ }
+
+ /* If there is no window manager, set the SDL_NOFRAME flag */
+ if ( ! video->info.wm_available ) {
+ mode->flags |= SDL_NOFRAME;
+ }
+
+ /* Reset the mouse cursor and grab for new video mode */
+ SDL_SetCursor(NULL);
+ if ( video->UpdateMouse ) {
+ video->UpdateMouse(this);
+ }
+ SDL_WM_GrabInput(saved_grab);
+ SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */
+
+#if SDL_VIDEO_OPENGL
+ /* Load GL symbols (before MakeCurrent, where we need glGetString). */
+ if ( flags & (SDL_OPENGL | SDL_OPENGLBLIT) ) {
+
+#if defined(__QNXNTO__) && (_NTO_VERSION < 630)
+#define __SDL_NOGETPROCADDR__
+#elif defined(__MINT__)
+#define __SDL_NOGETPROCADDR__
+#endif
+#ifdef __SDL_NOGETPROCADDR__
+ #define SDL_PROC(ret,func,params) video->func=func;
+#else
+ #define SDL_PROC(ret,func,params) \
+ do { \
+ video->func = SDL_GL_GetProcAddress(#func); \
+ if ( ! video->func ) { \
+ SDL_SetError("Couldn't load GL function %s: %s\n", #func, SDL_GetError()); \
+ return(NULL); \
+ } \
+ } while ( 0 );
+
+#endif /* __SDL_NOGETPROCADDR__ */
+
+#include "SDL_glfuncs.h"
+#undef SDL_PROC
+ }
+#endif /* SDL_VIDEO_OPENGL */
+
+ /* If we're running OpenGL, make the context current */
+ if ( (video->screen->flags & SDL_OPENGL) &&
+ video->GL_MakeCurrent ) {
+ if ( video->GL_MakeCurrent(this) < 0 ) {
+ return(NULL);
+ }
+ }
+
+ /* Set up a fake SDL surface for OpenGL "blitting" */
+ if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) {
+ /* Load GL functions for performing the texture updates */
+#if SDL_VIDEO_OPENGL
+
+ /* Create a software surface for blitting */
+#ifdef GL_VERSION_1_2
+ /* If the implementation either supports the packed pixels
+ extension, or implements the core OpenGL 1.2 API, it will
+ support the GL_UNSIGNED_SHORT_5_6_5 texture format.
+ */
+ if ( (bpp == 16) &&
+ (SDL_strstr((const char *)video->glGetString(GL_EXTENSIONS), "GL_EXT_packed_pixels") ||
+ (SDL_atof((const char *)video->glGetString(GL_VERSION)) >= 1.2f))
+ ) {
+ video->is_32bit = 0;
+ SDL_VideoSurface = SDL_CreateRGBSurface(
+ flags,
+ width,
+ height,
+ 16,
+ 31 << 11,
+ 63 << 5,
+ 31,
+ 0
+ );
+ }
+ else
+#endif /* OpenGL 1.2 */
+ {
+ video->is_32bit = 1;
+ SDL_VideoSurface = SDL_CreateRGBSurface(
+ flags,
+ width,
+ height,
+ 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000
+#else
+ 0xFF000000,
+ 0x00FF0000,
+ 0x0000FF00,
+ 0x000000FF
+#endif
+ );
+ }
+ if ( ! SDL_VideoSurface ) {
+ return(NULL);
+ }
+ SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT;
+
+ /* Free the original video mode surface (is this safe?) */
+ SDL_FreeSurface(mode);
+
+ /* Set the surface completely opaque & white by default */
+ SDL_memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch );
+ video->glGenTextures( 1, &video->texture );
+ video->glBindTexture( GL_TEXTURE_2D, video->texture );
+ video->glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ video->is_32bit ? GL_RGBA : GL_RGB,
+ 256,
+ 256,
+ 0,
+ video->is_32bit ? GL_RGBA : GL_RGB,
+#ifdef GL_VERSION_1_2
+ video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
+#else
+ GL_UNSIGNED_BYTE,
+#endif
+ NULL);
+
+ video->UpdateRects = SDL_GL_UpdateRectsLock;
+#else
+ SDL_SetError("Somebody forgot to #define SDL_VIDEO_OPENGL");
+ return(NULL);
+#endif
+ }
+
+ /* Create a shadow surface if necessary */
+ /* There are three conditions under which we create a shadow surface:
+ 1. We need a particular bits-per-pixel that we didn't get.
+ 2. We need a hardware palette and didn't get one.
+ 3. We need a software surface and got a hardware surface.
+ */
+ if ( !(SDL_VideoSurface->flags & SDL_OPENGL) &&
+ (
+ ( !(flags&SDL_ANYFORMAT) &&
+ (SDL_VideoSurface->format->BitsPerPixel != bpp)) ||
+ ( (flags&SDL_HWPALETTE) &&
+ !(SDL_VideoSurface->flags&SDL_HWPALETTE)) ||
+ /* If the surface is in hardware, video writes are visible
+ as soon as they are performed, so we need to buffer them
+ */
+ ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) &&
+ (SDL_VideoSurface->flags&SDL_HWSURFACE)) ||
+ ( (flags&SDL_DOUBLEBUF) &&
+ (SDL_VideoSurface->flags&SDL_HWSURFACE) &&
+ !(SDL_VideoSurface->flags&SDL_DOUBLEBUF))
+ ) ) {
+ SDL_CreateShadowSurface(bpp);
+ if ( SDL_ShadowSurface == NULL ) {
+ SDL_SetError("Couldn't create shadow surface");
+ return(NULL);
+ }
+ SDL_PublicSurface = SDL_ShadowSurface;
+ } else {
+ SDL_PublicSurface = SDL_VideoSurface;
+ }
+ video->info.vfmt = SDL_VideoSurface->format;
+ video->info.current_w = SDL_VideoSurface->w;
+ video->info.current_h = SDL_VideoSurface->h;
+
+ /* We're done! */
+ return(SDL_PublicSurface);
+}
+
+/*
+ * Convert a surface into the video pixel format.
+ */
+SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface)
+{
+ Uint32 flags;
+
+ if ( ! SDL_PublicSurface ) {
+ SDL_SetError("No video mode has been set");
+ return(NULL);
+ }
+ /* Set the flags appropriate for copying to display surface */
+ if (((SDL_PublicSurface->flags&SDL_HWSURFACE) == SDL_HWSURFACE) && current_video->info.blit_hw)
+ flags = SDL_HWSURFACE;
+ else
+ flags = SDL_SWSURFACE;
+#ifdef AUTORLE_DISPLAYFORMAT
+ flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));
+ flags |= SDL_RLEACCELOK;
+#else
+ flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK);
+#endif
+ return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));
+}
+
+/*
+ * Convert a surface into a format that's suitable for blitting to
+ * the screen, but including an alpha channel.
+ */
+SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface)
+{
+ SDL_PixelFormat *vf;
+ SDL_PixelFormat *format;
+ SDL_Surface *converted;
+ Uint32 flags;
+ /* default to ARGB8888 */
+ Uint32 amask = 0xff000000;
+ Uint32 rmask = 0x00ff0000;
+ Uint32 gmask = 0x0000ff00;
+ Uint32 bmask = 0x000000ff;
+
+ if ( ! SDL_PublicSurface ) {
+ SDL_SetError("No video mode has been set");
+ return(NULL);
+ }
+ vf = SDL_PublicSurface->format;
+
+ switch(vf->BytesPerPixel) {
+ case 2:
+ /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
+ For anything else (like ARGB4444) it doesn't matter
+ since we have no special code for it anyway */
+ if ( (vf->Rmask == 0x1f) &&
+ (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
+ rmask = 0xff;
+ bmask = 0xff0000;
+ }
+ break;
+
+ case 3:
+ case 4:
+ /* Keep the video format, as long as the high 8 bits are
+ unused or alpha */
+ if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) {
+ rmask = 0xff;
+ bmask = 0xff0000;
+ } else if ( vf->Rmask == 0xFF00 && (vf->Bmask == 0xFF000000) ) {
+ amask = 0x000000FF;
+ rmask = 0x0000FF00;
+ gmask = 0x00FF0000;
+ bmask = 0xFF000000;
+ }
+ break;
+
+ default:
+ /* We have no other optimised formats right now. When/if a new
+ optimised alpha format is written, add the converter here */
+ break;
+ }
+ format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
+ flags = SDL_PublicSurface->flags & SDL_HWSURFACE;
+ flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
+ converted = SDL_ConvertSurface(surface, format, flags);
+ SDL_FreeFormat(format);
+ return(converted);
+}
+
+/*
+ * Update a specific portion of the physical screen
+ */
+void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
+{
+ if ( screen ) {
+ SDL_Rect rect;
+
+ /* Perform some checking */
+ if ( w == 0 )
+ w = screen->w;
+ if ( h == 0 )
+ h = screen->h;
+ if ( (int)(x+w) > screen->w )
+ return;
+ if ( (int)(y+h) > screen->h )
+ return;
+
+ /* Fill the rectangle */
+ rect.x = (Sint16)x;
+ rect.y = (Sint16)y;
+ rect.w = (Uint16)w;
+ rect.h = (Uint16)h;
+ SDL_UpdateRects(screen, 1, &rect);
+ }
+}
+void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects)
+{
+ int i;
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( (screen->flags & (SDL_OPENGL | SDL_OPENGLBLIT)) == SDL_OPENGL ) {
+ SDL_SetError("OpenGL active, use SDL_GL_SwapBuffers()");
+ return;
+ }
+ if ( screen == SDL_ShadowSurface ) {
+ /* Blit the shadow surface using saved mapping */
+ SDL_Palette *pal = screen->format->palette;
+ SDL_Color *saved_colors = NULL;
+ if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
+ /* simulated 8bpp, use correct physical palette */
+ saved_colors = pal->colors;
+ if ( video->gammacols ) {
+ /* gamma-corrected palette */
+ pal->colors = video->gammacols;
+ } else if ( video->physpal ) {
+ /* physical palette different from logical */
+ pal->colors = video->physpal->colors;
+ }
+ }
+ if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
+ SDL_LockCursor();
+ SDL_DrawCursor(SDL_ShadowSurface);
+ for ( i=0; i<numrects; ++i ) {
+ SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
+ SDL_VideoSurface, &rects[i]);
+ }
+ SDL_EraseCursor(SDL_ShadowSurface);
+ SDL_UnlockCursor();
+ } else {
+ for ( i=0; i<numrects; ++i ) {
+ SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
+ SDL_VideoSurface, &rects[i]);
+ }
+ }
+ if ( saved_colors ) {
+ pal->colors = saved_colors;
+ }
+
+ /* Fall through to video surface update */
+ screen = SDL_VideoSurface;
+ }
+ if ( screen == SDL_VideoSurface ) {
+ /* Update the video surface */
+ if ( screen->offset ) {
+ for ( i=0; i<numrects; ++i ) {
+ rects[i].x += video->offset_x;
+ rects[i].y += video->offset_y;
+ }
+ video->UpdateRects(this, numrects, rects);
+ for ( i=0; i<numrects; ++i ) {
+ rects[i].x -= video->offset_x;
+ rects[i].y -= video->offset_y;
+ }
+ } else {
+ video->UpdateRects(this, numrects, rects);
+ }
+ }
+}
+
+/*
+ * Performs hardware double buffering, if possible, or a full update if not.
+ */
+int SDL_Flip(SDL_Surface *screen)
+{
+ SDL_VideoDevice *video = current_video;
+ /* Copy the shadow surface to the video surface */
+ if ( screen == SDL_ShadowSurface ) {
+ SDL_Rect rect;
+ SDL_Palette *pal = screen->format->palette;
+ SDL_Color *saved_colors = NULL;
+ if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
+ /* simulated 8bpp, use correct physical palette */
+ saved_colors = pal->colors;
+ if ( video->gammacols ) {
+ /* gamma-corrected palette */
+ pal->colors = video->gammacols;
+ } else if ( video->physpal ) {
+ /* physical palette different from logical */
+ pal->colors = video->physpal->colors;
+ }
+ }
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = screen->w;
+ rect.h = screen->h;
+ if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
+ SDL_LockCursor();
+ SDL_DrawCursor(SDL_ShadowSurface);
+ SDL_LowerBlit(SDL_ShadowSurface, &rect,
+ SDL_VideoSurface, &rect);
+ SDL_EraseCursor(SDL_ShadowSurface);
+ SDL_UnlockCursor();
+ } else {
+ SDL_LowerBlit(SDL_ShadowSurface, &rect,
+ SDL_VideoSurface, &rect);
+ }
+ if ( saved_colors ) {
+ pal->colors = saved_colors;
+ }
+
+ /* Fall through to video surface update */
+ screen = SDL_VideoSurface;
+ }
+ if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ SDL_VideoDevice *this = current_video;
+ return(video->FlipHWSurface(this, SDL_VideoSurface));
+ } else {
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
+ return(0);
+}
+
+static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors,
+ int firstcolor, int ncolors)
+{
+ SDL_Palette *pal = screen->format->palette;
+ SDL_Palette *vidpal;
+
+ if ( colors != (pal->colors + firstcolor) ) {
+ SDL_memcpy(pal->colors + firstcolor, colors,
+ ncolors * sizeof(*colors));
+ }
+
+ if ( current_video && SDL_VideoSurface ) {
+ vidpal = SDL_VideoSurface->format->palette;
+ if ( (screen == SDL_ShadowSurface) && vidpal ) {
+ /*
+ * This is a shadow surface, and the physical
+ * framebuffer is also indexed. Propagate the
+ * changes to its logical palette so that
+ * updates are always identity blits
+ */
+ SDL_memcpy(vidpal->colors + firstcolor, colors,
+ ncolors * sizeof(*colors));
+ }
+ }
+ SDL_FormatChanged(screen);
+}
+
+static int SetPalette_physical(SDL_Surface *screen,
+ SDL_Color *colors, int firstcolor, int ncolors)
+{
+ SDL_VideoDevice *video = current_video;
+ int gotall = 1;
+
+ if ( video->physpal ) {
+ /* We need to copy the new colors, since we haven't
+ * already done the copy in the logical set above.
+ */
+ SDL_memcpy(video->physpal->colors + firstcolor,
+ colors, ncolors * sizeof(*colors));
+ }
+ if ( screen == SDL_ShadowSurface ) {
+ if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) {
+ /*
+ * The real screen is also indexed - set its physical
+ * palette. The physical palette does not include the
+ * gamma modification, we apply it directly instead,
+ * but this only happens if we have hardware palette.
+ */
+ screen = SDL_VideoSurface;
+ } else {
+ /*
+ * The video surface is not indexed - invalidate any
+ * active shadow-to-video blit mappings.
+ */
+ if ( screen->map->dst == SDL_VideoSurface ) {
+ SDL_InvalidateMap(screen->map);
+ }
+ if ( video->gamma ) {
+ if( ! video->gammacols ) {
+ SDL_Palette *pp = video->physpal;
+ if(!pp)
+ pp = screen->format->palette;
+ video->gammacols = SDL_malloc(pp->ncolors
+ * sizeof(SDL_Color));
+ SDL_ApplyGamma(video->gamma,
+ pp->colors,
+ video->gammacols,
+ pp->ncolors);
+ } else {
+ SDL_ApplyGamma(video->gamma, colors,
+ video->gammacols
+ + firstcolor,
+ ncolors);
+ }
+ }
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
+ }
+
+ if ( screen == SDL_VideoSurface ) {
+ SDL_Color gcolors[256];
+
+ if ( video->gamma ) {
+ SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors);
+ colors = gcolors;
+ }
+ gotall = video->SetColors(video, firstcolor, ncolors, colors);
+ if ( ! gotall ) {
+ /* The video flags shouldn't have SDL_HWPALETTE, and
+ the video driver is responsible for copying back the
+ correct colors into the video surface palette.
+ */
+ ;
+ }
+ SDL_CursorPaletteChanged();
+ }
+ return gotall;
+}
+
+/*
+ * Set the physical and/or logical colormap of a surface:
+ * Only the screen has a physical colormap. It determines what is actually
+ * sent to the display.
+ * The logical colormap is used to map blits to/from the surface.
+ * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL
+ *
+ * Return nonzero if all colours were set as requested, or 0 otherwise.
+ */
+int SDL_SetPalette(SDL_Surface *screen, int which,
+ SDL_Color *colors, int firstcolor, int ncolors)
+{
+ SDL_Palette *pal;
+ int gotall;
+ int palsize;
+
+ if ( !screen ) {
+ return 0;
+ }
+ if ( !current_video || screen != SDL_PublicSurface ) {
+ /* only screens have physical palettes */
+ which &= ~SDL_PHYSPAL;
+ } else if ( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) {
+ /* hardware palettes required for split colormaps */
+ which |= SDL_PHYSPAL | SDL_LOGPAL;
+ }
+
+ /* Verify the parameters */
+ pal = screen->format->palette;
+ if( !pal ) {
+ return 0; /* not a palettized surface */
+ }
+ gotall = 1;
+ palsize = 1 << screen->format->BitsPerPixel;
+ if ( ncolors > (palsize - firstcolor) ) {
+ ncolors = (palsize - firstcolor);
+ gotall = 0;
+ }
+
+ if ( which & SDL_LOGPAL ) {
+ /*
+ * Logical palette change: The actual screen isn't affected,
+ * but the internal colormap is altered so that the
+ * interpretation of the pixel values (for blits etc) is
+ * changed.
+ */
+ SetPalette_logical(screen, colors, firstcolor, ncolors);
+ }
+ if ( which & SDL_PHYSPAL ) {
+ SDL_VideoDevice *video = current_video;
+ /*
+ * Physical palette change: This doesn't affect the
+ * program's idea of what the screen looks like, but changes
+ * its actual appearance.
+ */
+ if ( !video->physpal && !(which & SDL_LOGPAL) ) {
+ /* Lazy physical palette allocation */
+ int size;
+ SDL_Palette *pp = SDL_malloc(sizeof(*pp));
+ if ( !pp ) {
+ return 0;
+ }
+ video->physpal = pp;
+ pp->ncolors = pal->ncolors;
+ size = pp->ncolors * sizeof(SDL_Color);
+ pp->colors = SDL_malloc(size);
+ if ( !pp->colors ) {
+ return 0;
+ }
+ SDL_memcpy(pp->colors, pal->colors, size);
+ }
+ if ( ! SetPalette_physical(screen,
+ colors, firstcolor, ncolors) ) {
+ gotall = 0;
+ }
+ }
+ return gotall;
+}
+
+int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor,
+ int ncolors)
+{
+ return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
+ colors, firstcolor, ncolors);
+}
+
+/*
+ * Clean up the video subsystem
+ */
+void SDL_VideoQuit (void)
+{
+ SDL_Surface *ready_to_go;
+
+ if ( current_video ) {
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ /* Halt event processing before doing anything else */
+ SDL_StopEventLoop();
+
+ /* Clean up allocated window manager items */
+ if ( SDL_PublicSurface ) {
+ SDL_PublicSurface = NULL;
+ }
+ SDL_CursorQuit();
+
+ /* Just in case... */
+ SDL_WM_GrabInputOff();
+
+ /* Clean up the system video */
+ video->VideoQuit(this);
+
+ /* Free any lingering surfaces */
+ ready_to_go = SDL_ShadowSurface;
+ SDL_ShadowSurface = NULL;
+ SDL_FreeSurface(ready_to_go);
+ if ( SDL_VideoSurface != NULL ) {
+ ready_to_go = SDL_VideoSurface;
+ SDL_VideoSurface = NULL;
+ SDL_FreeSurface(ready_to_go);
+ }
+ SDL_PublicSurface = NULL;
+
+ /* Clean up miscellaneous memory */
+ if ( video->physpal ) {
+ SDL_free(video->physpal->colors);
+ SDL_free(video->physpal);
+ video->physpal = NULL;
+ }
+ if ( video->gammacols ) {
+ SDL_free(video->gammacols);
+ video->gammacols = NULL;
+ }
+ if ( video->gamma ) {
+ SDL_free(video->gamma);
+ video->gamma = NULL;
+ }
+ if ( video->wm_title != NULL ) {
+ SDL_free(video->wm_title);
+ video->wm_title = NULL;
+ }
+ if ( video->wm_icon != NULL ) {
+ SDL_free(video->wm_icon);
+ video->wm_icon = NULL;
+ }
+
+ /* Finish cleaning up video subsystem */
+ video->free(this);
+ current_video = NULL;
+ }
+ return;
+}
+
+/* Load the GL driver library */
+int SDL_GL_LoadLibrary(const char *path)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ int retval;
+
+ retval = -1;
+ if ( video == NULL ) {
+ SDL_SetError("Video subsystem has not been initialized");
+ } else {
+ if ( video->GL_LoadLibrary ) {
+ retval = video->GL_LoadLibrary(this, path);
+ } else {
+ SDL_SetError("No dynamic GL support in video driver");
+ }
+ }
+ return(retval);
+}
+
+void *SDL_GL_GetProcAddress(const char* proc)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ void *func;
+
+ func = NULL;
+ if ( video->GL_GetProcAddress ) {
+ if ( video->gl_config.driver_loaded ) {
+ func = video->GL_GetProcAddress(this, proc);
+ } else {
+ SDL_SetError("No GL driver has been loaded");
+ }
+ } else {
+ SDL_SetError("No dynamic GL support in video driver");
+ }
+ return func;
+}
+
+/* Set the specified GL attribute for setting up a GL video mode */
+int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
+{
+ int retval;
+ SDL_VideoDevice *video = current_video;
+
+ retval = 0;
+ switch (attr) {
+ case SDL_GL_RED_SIZE:
+ video->gl_config.red_size = value;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ video->gl_config.green_size = value;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ video->gl_config.blue_size = value;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ video->gl_config.alpha_size = value;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ video->gl_config.double_buffer = value;
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ video->gl_config.buffer_size = value;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ video->gl_config.depth_size = value;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ video->gl_config.stencil_size = value;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ video->gl_config.accum_red_size = value;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ video->gl_config.accum_green_size = value;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ video->gl_config.accum_blue_size = value;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ video->gl_config.accum_alpha_size = value;
+ break;
+ case SDL_GL_STEREO:
+ video->gl_config.stereo = value;
+ break;
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ video->gl_config.multisamplebuffers = value;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ video->gl_config.multisamplesamples = value;
+ break;
+ case SDL_GL_ACCELERATED_VISUAL:
+ video->gl_config.accelerated = value;
+ break;
+ case SDL_GL_SWAP_CONTROL:
+ video->gl_config.swap_control = value;
+ break;
+ default:
+ SDL_SetError("Unknown OpenGL attribute");
+ retval = -1;
+ break;
+ }
+ return(retval);
+}
+
+/* Retrieve an attribute value from the windowing system. */
+int SDL_GL_GetAttribute(SDL_GLattr attr, int* value)
+{
+ int retval = -1;
+ SDL_VideoDevice* video = current_video;
+ SDL_VideoDevice* this = current_video;
+
+ if ( video->GL_GetAttribute ) {
+ retval = this->GL_GetAttribute(this, attr, value);
+ } else {
+ *value = 0;
+ SDL_SetError("GL_GetAttribute not supported");
+ }
+ return retval;
+}
+
+/* Perform a GL buffer swap on the current GL context */
+void SDL_GL_SwapBuffers(void)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( video->screen->flags & SDL_OPENGL ) {
+ video->GL_SwapBuffers(this);
+ } else {
+ SDL_SetError("OpenGL video mode has not been set");
+ }
+}
+
+/* Update rects with locking */
+void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects)
+{
+ SDL_GL_Lock();
+ SDL_GL_UpdateRects(numrects, rects);
+ SDL_GL_Unlock();
+}
+
+/* Update rects without state setting and changing (the caller is responsible for it) */
+void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects)
+{
+#if SDL_VIDEO_OPENGL
+ SDL_VideoDevice *this = current_video;
+ SDL_Rect update, tmp;
+ int x, y, i;
+
+ for ( i = 0; i < numrects; i++ )
+ {
+ tmp.y = rects[i].y;
+ tmp.h = rects[i].h;
+ for ( y = 0; y <= rects[i].h / 256; y++ )
+ {
+ tmp.x = rects[i].x;
+ tmp.w = rects[i].w;
+ for ( x = 0; x <= rects[i].w / 256; x++ )
+ {
+ update.x = tmp.x;
+ update.y = tmp.y;
+ update.w = tmp.w;
+ update.h = tmp.h;
+
+ if ( update.w > 256 )
+ update.w = 256;
+
+ if ( update.h > 256 )
+ update.h = 256;
+
+ this->glFlush();
+ this->glTexSubImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ 0,
+ 0,
+ update.w,
+ update.h,
+ this->is_32bit? GL_RGBA : GL_RGB,
+#ifdef GL_VERSION_1_2
+ this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
+#else
+ GL_UNSIGNED_BYTE,
+#endif
+ (Uint8 *)this->screen->pixels +
+ this->screen->format->BytesPerPixel * update.x +
+ update.y * this->screen->pitch );
+
+ this->glFlush();
+ /*
+ * Note the parens around the function name:
+ * This is because some OpenGL implementations define glTexCoord etc
+ * as macros, and we don't want them expanded here.
+ */
+ this->glBegin(GL_TRIANGLE_STRIP);
+ (this->glTexCoord2f)( 0.0, 0.0 );
+ (this->glVertex2i)( update.x, update.y );
+ (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 );
+ (this->glVertex2i)( update.x + update.w, update.y );
+ (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) );
+ (this->glVertex2i)( update.x, update.y + update.h );
+ (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) );
+ (this->glVertex2i)( update.x + update.w , update.y + update.h );
+ this->glEnd();
+
+ tmp.x += 256;
+ tmp.w -= 256;
+ }
+ tmp.y += 256;
+ tmp.h -= 256;
+ }
+ }
+#endif
+}
+
+/* Lock == save current state */
+void SDL_GL_Lock()
+{
+#if SDL_VIDEO_OPENGL
+ lock_count--;
+ if (lock_count==-1)
+ {
+ SDL_VideoDevice *this = current_video;
+
+ this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */
+#ifdef GL_CLIENT_PIXEL_STORE_BIT
+ this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
+#endif
+
+ this->glEnable(GL_TEXTURE_2D);
+ this->glEnable(GL_BLEND);
+ this->glDisable(GL_FOG);
+ this->glDisable(GL_ALPHA_TEST);
+ this->glDisable(GL_DEPTH_TEST);
+ this->glDisable(GL_SCISSOR_TEST);
+ this->glDisable(GL_STENCIL_TEST);
+ this->glDisable(GL_CULL_FACE);
+
+ this->glBindTexture( GL_TEXTURE_2D, this->texture );
+ this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+
+ this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel );
+ this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */
+
+ this->glViewport(0, 0, this->screen->w, this->screen->h);
+ this->glMatrixMode(GL_PROJECTION);
+ this->glPushMatrix();
+ this->glLoadIdentity();
+
+ this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0);
+
+ this->glMatrixMode(GL_MODELVIEW);
+ this->glPushMatrix();
+ this->glLoadIdentity();
+ }
+#endif
+}
+
+/* Unlock == restore saved state */
+void SDL_GL_Unlock()
+{
+#if SDL_VIDEO_OPENGL
+ lock_count++;
+ if (lock_count==0)
+ {
+ SDL_VideoDevice *this = current_video;
+
+ this->glPopMatrix();
+ this->glMatrixMode(GL_PROJECTION);
+ this->glPopMatrix();
+
+ this->glPopClientAttrib();
+ this->glPopAttrib();
+ }
+#endif
+}
+
+#if SDL_AUDIO_DRIVER_PULSE
+void SDL_Audio_SetCaption(const char *caption);
+#endif
+
+/*
+ * Sets/Gets the title and icon text of the display window, if any.
+ */
+void SDL_WM_SetCaption (const char *title, const char *icon)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( video ) {
+ if ( title ) {
+ if ( video->wm_title ) {
+ SDL_free(video->wm_title);
+ }
+ video->wm_title = SDL_strdup(title);
+ }
+ if ( icon ) {
+ if ( video->wm_icon ) {
+ SDL_free(video->wm_icon);
+ }
+ video->wm_icon = SDL_strdup(icon);
+ }
+ if ( (title || icon) && (video->SetCaption != NULL) ) {
+ video->SetCaption(this, video->wm_title,video->wm_icon);
+ }
+ }
+
+#if SDL_AUDIO_DRIVER_PULSE
+ /* PulseAudio can make use of this information. */
+ SDL_Audio_SetCaption(title);
+#endif
+}
+
+void SDL_WM_GetCaption (char **title, char **icon)
+{
+ SDL_VideoDevice *video = current_video;
+
+ if ( video ) {
+ if ( title ) {
+ *title = video->wm_title;
+ }
+ if ( icon ) {
+ *icon = video->wm_icon;
+ }
+ }
+}
+
+/* Utility function used by SDL_WM_SetIcon();
+ * flags & 1 for color key, flags & 2 for alpha channel. */
+static void CreateMaskFromColorKeyOrAlpha(SDL_Surface *icon, Uint8 *mask, int flags)
+{
+ int x, y;
+ Uint32 colorkey;
+#define SET_MASKBIT(icon, x, y, mask) \
+ mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8)))
+
+ colorkey = icon->format->colorkey;
+ switch (icon->format->BytesPerPixel) {
+ case 1: { Uint8 *pixels;
+ for ( y=0; y<icon->h; ++y ) {
+ pixels = (Uint8 *)icon->pixels + y*icon->pitch;
+ for ( x=0; x<icon->w; ++x ) {
+ if ( *pixels++ == colorkey ) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ }
+ }
+ }
+ break;
+
+ case 2: { Uint16 *pixels;
+ for ( y=0; y<icon->h; ++y ) {
+ pixels = (Uint16 *)icon->pixels +
+ y*icon->pitch/2;
+ for ( x=0; x<icon->w; ++x ) {
+ if ( (flags & 1) && *pixels == colorkey ) {
+ SET_MASKBIT(icon, x, y, mask);
+ } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ pixels++;
+ }
+ }
+ }
+ break;
+
+ case 4: { Uint32 *pixels;
+ for ( y=0; y<icon->h; ++y ) {
+ pixels = (Uint32 *)icon->pixels +
+ y*icon->pitch/4;
+ for ( x=0; x<icon->w; ++x ) {
+ if ( (flags & 1) && *pixels == colorkey ) {
+ SET_MASKBIT(icon, x, y, mask);
+ } else if((flags & 2) && (*pixels & icon->format->Amask) == 0) {
+ SET_MASKBIT(icon, x, y, mask);
+ }
+ pixels++;
+ }
+ }
+ }
+ break;
+ }
+}
+
+/*
+ * Sets the window manager icon for the display window.
+ */
+void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( icon && video->SetIcon ) {
+ /* Generate a mask if necessary, and create the icon! */
+ if ( mask == NULL ) {
+ int mask_len = icon->h*(icon->w+7)/8;
+ int flags = 0;
+ mask = (Uint8 *)SDL_malloc(mask_len);
+ if ( mask == NULL ) {
+ return;
+ }
+ SDL_memset(mask, ~0, mask_len);
+ if ( icon->flags & SDL_SRCCOLORKEY ) flags |= 1;
+ if ( icon->flags & SDL_SRCALPHA ) flags |= 2;
+ if( flags ) {
+ CreateMaskFromColorKeyOrAlpha(icon, mask, flags);
+ }
+ video->SetIcon(video, icon, mask);
+ SDL_free(mask);
+ } else {
+ video->SetIcon(this, icon, mask);
+ }
+ }
+}
+
+/*
+ * Grab or ungrab the keyboard and mouse input.
+ * This function returns the final grab mode after calling the
+ * driver dependent function.
+ */
+static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ /* Only do something if we have support for grabs */
+ if ( video->GrabInput == NULL ) {
+ return(video->input_grab);
+ }
+
+ /* If the final grab mode if off, only then do we actually grab */
+#ifdef DEBUG_GRAB
+ printf("SDL_WM_GrabInputRaw(%d) ... ", mode);
+#endif
+ if ( mode == SDL_GRAB_OFF ) {
+ if ( video->input_grab != SDL_GRAB_OFF ) {
+ mode = video->GrabInput(this, mode);
+ }
+ } else {
+ if ( video->input_grab == SDL_GRAB_OFF ) {
+ mode = video->GrabInput(this, mode);
+ }
+ }
+ if ( mode != video->input_grab ) {
+ video->input_grab = mode;
+ if ( video->CheckMouseMode ) {
+ video->CheckMouseMode(this);
+ }
+ }
+#ifdef DEBUG_GRAB
+ printf("Final mode %d\n", video->input_grab);
+#endif
+
+ /* Return the final grab state */
+ if ( mode >= SDL_GRAB_FULLSCREEN ) {
+ mode -= SDL_GRAB_FULLSCREEN;
+ }
+ return(mode);
+}
+SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode)
+{
+ SDL_VideoDevice *video = current_video;
+
+ /* If the video isn't initialized yet, we can't do anything */
+ if ( ! video ) {
+ return SDL_GRAB_OFF;
+ }
+
+ /* Return the current mode on query */
+ if ( mode == SDL_GRAB_QUERY ) {
+ mode = video->input_grab;
+ if ( mode >= SDL_GRAB_FULLSCREEN ) {
+ mode -= SDL_GRAB_FULLSCREEN;
+ }
+ return(mode);
+ }
+
+#ifdef DEBUG_GRAB
+ printf("SDL_WM_GrabInput(%d) ... ", mode);
+#endif
+ /* If the video surface is fullscreen, we always grab */
+ if ( mode >= SDL_GRAB_FULLSCREEN ) {
+ mode -= SDL_GRAB_FULLSCREEN;
+ }
+ if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) {
+ mode += SDL_GRAB_FULLSCREEN;
+ }
+ return(SDL_WM_GrabInputRaw(mode));
+}
+static SDL_GrabMode SDL_WM_GrabInputOff(void)
+{
+ SDL_GrabMode mode;
+
+ /* First query the current grab state */
+ mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
+
+ /* Now explicitly turn off input grab */
+ SDL_WM_GrabInputRaw(SDL_GRAB_OFF);
+
+ /* Return the old state */
+ return(mode);
+}
+
+/*
+ * Iconify the window in window managed environments.
+ * A successful iconification will result in an SDL_APPACTIVE loss event.
+ */
+int SDL_WM_IconifyWindow(void)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ int retval;
+
+ retval = 0;
+ if ( video->IconifyWindow ) {
+ retval = video->IconifyWindow(this);
+ }
+ return(retval);
+}
+
+/*
+ * Toggle fullscreen mode
+ */
+int SDL_WM_ToggleFullScreen(SDL_Surface *surface)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ int toggled;
+
+ toggled = 0;
+ if ( SDL_PublicSurface && (surface == SDL_PublicSurface) &&
+ video->ToggleFullScreen ) {
+ if ( surface->flags & SDL_FULLSCREEN ) {
+ toggled = video->ToggleFullScreen(this, 0);
+ if ( toggled ) {
+ SDL_VideoSurface->flags &= ~SDL_FULLSCREEN;
+ SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
+ }
+ } else {
+ toggled = video->ToggleFullScreen(this, 1);
+ if ( toggled ) {
+ SDL_VideoSurface->flags |= SDL_FULLSCREEN;
+ SDL_PublicSurface->flags |= SDL_FULLSCREEN;
+ }
+ }
+ /* Double-check the grab state inside SDL_WM_GrabInput() */
+ if ( toggled ) {
+ SDL_WM_GrabInput(video->input_grab);
+ }
+ }
+ return(toggled);
+}
+
+/*
+ * Set window position
+ */
+void SDL_WM_SetPos(int x, int y)
+{
+ SDL_VideoDevice* video = current_video;
+
+ if (video && video->SetWindowPos)
+ video->SetWindowPos(video, x, y);
+}
+
+/*
+ * Get window position
+ */
+void SDL_WM_GetPos(int *px, int *py)
+{
+ SDL_VideoDevice* video = current_video;
+
+ if (video && video->GetWindowPos)
+ video->GetWindowPos(video, px, py);
+ else {
+ *px = 100;
+ *py = 100;
+ }
+}
+
+int SDL_WM_IsFullyVisible( int recenter )
+{
+ int result = 1;
+
+ SDL_VideoDevice* video = current_video;
+
+ if (video && video->IsWindowVisible) {
+ result = video->IsWindowVisible(video, recenter);
+ }
+ return result;
+}
+
+int SDL_WM_GetMonitorDPI( int *xDpi, int *yDpi )
+{
+ int result = -1;
+ SDL_VideoDevice* video = current_video;
+
+ if (video && video->GetMonitorDPI) {
+ result = video->GetMonitorDPI(video, xDpi, yDpi);
+ }
+ return result;
+}
+
+int SDL_WM_GetMonitorRect( SDL_Rect *rect )
+{
+ int result = -1;
+ SDL_VideoDevice* video = current_video;
+
+ if (video && video->GetMonitorRect) {
+ result = video->GetMonitorRect(video, rect);
+ }
+ return result;
+}
+
+/*
+ * Get some platform dependent window manager information
+ */
+int SDL_GetWMInfo (SDL_SysWMinfo *info)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+
+ if ( video && video->GetWMInfo ) {
+ return(video->GetWMInfo(this, info));
+ } else {
+ return(0);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_yuv.c b/distrib/sdl-1.2.15/src/video/SDL_yuv.c
new file mode 100644
index 0000000..eea3347
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_yuv.c
@@ -0,0 +1,150 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the implementation of the YUV video surface support */
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+#include "SDL_yuvfuncs.h"
+#include "SDL_yuv_sw_c.h"
+
+
+SDL_Overlay *SDL_CreateYUVOverlay(int w, int h, Uint32 format,
+ SDL_Surface *display)
+{
+ SDL_VideoDevice *video = current_video;
+ SDL_VideoDevice *this = current_video;
+ const char *yuv_hwaccel;
+ SDL_Overlay *overlay;
+
+ if ( (display->flags & SDL_OPENGL) == SDL_OPENGL ) {
+ SDL_SetError("YUV overlays are not supported in OpenGL mode");
+ return NULL;
+ }
+
+ /* Display directly on video surface, if possible */
+ if ( SDL_getenv("SDL_VIDEO_YUV_DIRECT") ) {
+ if ( (display == SDL_PublicSurface) &&
+ ((SDL_VideoSurface->format->BytesPerPixel == 2) ||
+ (SDL_VideoSurface->format->BytesPerPixel == 4)) ) {
+ display = SDL_VideoSurface;
+ }
+ }
+ overlay = NULL;
+ yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL");
+ if ( ((display == SDL_VideoSurface) && video->CreateYUVOverlay) &&
+ (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0)) ) {
+ overlay = video->CreateYUVOverlay(this, w, h, format, display);
+ }
+ /* If hardware YUV overlay failed ... */
+ if ( overlay == NULL ) {
+ overlay = SDL_CreateYUV_SW(this, w, h, format, display);
+ }
+ return overlay;
+}
+
+int SDL_LockYUVOverlay(SDL_Overlay *overlay)
+{
+ if ( overlay == NULL ) {
+ SDL_SetError("Passed NULL overlay");
+ return -1;
+ }
+ return overlay->hwfuncs->Lock(current_video, overlay);
+}
+
+void SDL_UnlockYUVOverlay(SDL_Overlay *overlay)
+{
+ if ( overlay == NULL ) {
+ return;
+ }
+ overlay->hwfuncs->Unlock(current_video, overlay);
+}
+
+int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect)
+{
+ SDL_Rect src, dst;
+ int srcx, srcy, srcw, srch;
+ int dstx, dsty, dstw, dsth;
+
+ if ( overlay == NULL || dstrect == NULL ) {
+ SDL_SetError("Passed NULL overlay or dstrect");
+ return -1;
+ }
+
+ /* Clip the rectangle to the screen area */
+ srcx = 0;
+ srcy = 0;
+ srcw = overlay->w;
+ srch = overlay->h;
+ dstx = dstrect->x;
+ dsty = dstrect->y;
+ dstw = dstrect->w;
+ dsth = dstrect->h;
+ if ( dstx < 0 ) {
+ srcw += (dstx * overlay->w) / dstrect->w;
+ dstw += dstx;
+ srcx -= (dstx * overlay->w) / dstrect->w;
+ dstx = 0;
+ }
+ if ( (dstx+dstw) > current_video->screen->w ) {
+ int extra = (dstx+dstw - current_video->screen->w);
+ srcw -= (extra * overlay->w) / dstrect->w;
+ dstw -= extra;
+ }
+ if ( dsty < 0 ) {
+ srch += (dsty * overlay->h) / dstrect->h;
+ dsth += dsty;
+ srcy -= (dsty * overlay->h) / dstrect->h;
+ dsty = 0;
+ }
+ if ( (dsty+dsth) > current_video->screen->h ) {
+ int extra = (dsty+dsth - current_video->screen->h);
+ srch -= (extra * overlay->h) / dstrect->h;
+ dsth -= extra;
+ }
+ if ( srcw <= 0 || srch <= 0 ||
+ srch <= 0 || dsth <= 0 ) {
+ return 0;
+ }
+ /* Ugh, I can't wait for SDL_Rect to be int values */
+ src.x = srcx;
+ src.y = srcy;
+ src.w = srcw;
+ src.h = srch;
+ dst.x = dstx;
+ dst.y = dsty;
+ dst.w = dstw;
+ dst.h = dsth;
+ return overlay->hwfuncs->Display(current_video, overlay, &src, &dst);
+}
+
+void SDL_FreeYUVOverlay(SDL_Overlay *overlay)
+{
+ if ( overlay == NULL ) {
+ return;
+ }
+ if ( overlay->hwfuncs ) {
+ overlay->hwfuncs->FreeHW(current_video, overlay);
+ }
+ SDL_free(overlay);
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_yuv_mmx.c b/distrib/sdl-1.2.15/src/video/SDL_yuv_mmx.c
new file mode 100644
index 0000000..f11c432
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_yuv_mmx.c
@@ -0,0 +1,428 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES
+
+#include "SDL_stdinc.h"
+
+#include "mmx.h"
+
+/* *INDENT-OFF* */
+
+static mmx_t MMX_0080w = { .ud = {0x00800080, 0x00800080} };
+static mmx_t MMX_00FFw = { .ud = {0x00ff00ff, 0x00ff00ff} };
+static mmx_t MMX_FF00w = { .ud = {0xff00ff00, 0xff00ff00} };
+
+static mmx_t MMX_Ycoeff = { .uw = {0x004a, 0x004a, 0x004a, 0x004a} };
+
+static mmx_t MMX_UbluRGB = { .uw = {0x0072, 0x0072, 0x0072, 0x0072} };
+static mmx_t MMX_VredRGB = { .uw = {0x0059, 0x0059, 0x0059, 0x0059} };
+static mmx_t MMX_UgrnRGB = { .uw = {0xffea, 0xffea, 0xffea, 0xffea} };
+static mmx_t MMX_VgrnRGB = { .uw = {0xffd2, 0xffd2, 0xffd2, 0xffd2} };
+
+static mmx_t MMX_Ublu5x5 = { .uw = {0x0081, 0x0081, 0x0081, 0x0081} };
+static mmx_t MMX_Vred5x5 = { .uw = {0x0066, 0x0066, 0x0066, 0x0066} };
+static mmx_t MMX_Ugrn565 = { .uw = {0xffe8, 0xffe8, 0xffe8, 0xffe8} };
+static mmx_t MMX_Vgrn565 = { .uw = {0xffcd, 0xffcd, 0xffcd, 0xffcd} };
+
+static mmx_t MMX_red565 = { .uw = {0xf800, 0xf800, 0xf800, 0xf800} };
+static mmx_t MMX_grn565 = { .uw = {0x07e0, 0x07e0, 0x07e0, 0x07e0} };
+
+/**
+ This MMX assembler is my first assembler/MMX program ever.
+ Thus it maybe buggy.
+ Send patches to:
+ mvogt@rhrk.uni-kl.de
+
+ After it worked fine I have "obfuscated" the code a bit to have
+ more parallism in the MMX units. This means I moved
+ initilisation around and delayed other instruction.
+ Performance measurement did not show that this brought any advantage
+ but in theory it _should_ be faster this way.
+
+ The overall performanve gain to the C based dither was 30%-40%.
+ The MMX routine calculates 256bit=8RGB values in each cycle
+ (4 for row1 & 4 for row2)
+
+ The red/green/blue.. coefficents are taken from the mpeg_play
+ player. They look nice, but I dont know if you can have
+ better values, to avoid integer rounding errors.
+
+
+ IMPORTANT:
+ ==========
+
+ It is a requirement that the cr/cb/lum are 8 byte aligned and
+ the out are 16byte aligned or you will/may get segfaults
+
+*/
+
+void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ Uint32 *row1;
+ Uint32 *row2;
+
+ unsigned char* y = lum +cols*rows; // Pointer to the end
+ int x = 0;
+ row1 = (Uint32 *)out; // 32 bit target
+ row2 = (Uint32 *)out+cols+mod; // start of second row
+ mod = (mod+cols+mod)*4; // increment for row1 in byte
+
+ __asm__ __volatile__ (
+ // tap dance to workaround the inability to use %%ebx at will...
+ // move one thing to the stack...
+ "pushl $0\n" // save a slot on the stack.
+ "pushl %%ebx\n" // save %%ebx.
+ "movl %0, %%ebx\n" // put the thing in ebx.
+ "movl %%ebx,4(%%esp)\n" // put the thing in the stack slot.
+ "popl %%ebx\n" // get back %%ebx (the PIC register).
+
+ ".align 8\n"
+ "1:\n"
+
+ // create Cr (result in mm1)
+ "pushl %%ebx\n"
+ "movl 4(%%esp),%%ebx\n"
+ "movd (%%ebx),%%mm1\n" // 0 0 0 0 v3 v2 v1 v0
+ "popl %%ebx\n"
+ "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00
+ "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0
+ "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0
+ "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0
+ "psubw %9,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0
+
+ // create Cr_g (result in mm0)
+ "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0
+ "pmullw %10,%%mm0\n" // red*-46dec=0.7136*64
+ "pmullw %11,%%mm1\n" // red*89dec=1.4013*64
+ "psraw $6, %%mm0\n" // red=red/64
+ "psraw $6, %%mm1\n" // red=red/64
+
+ // create L1 L2 (result in mm2,mm4)
+ // L2=lum+cols
+ "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0
+ "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0
+ "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0
+ "pand %12,%%mm2\n" // L3 0 L1 0 l3 0 l1 0
+ "pand %13,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0
+ "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1
+
+ // create R (result in mm6)
+ "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0
+ "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1
+ "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0
+ "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1
+ "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0
+ "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00
+ "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0
+
+ // create Cb (result in mm1)
+ "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0
+ "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0
+ "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0
+ "psubw %9,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0
+ // create Cb_g (result in mm5)
+ "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0
+ "pmullw %14,%%mm5\n" // blue*-109dec=1.7129*64
+ "pmullw %15,%%mm1\n" // blue*114dec=1.78125*64
+ "psraw $6, %%mm5\n" // blue=red/64
+ "psraw $6, %%mm1\n" // blue=blue/64
+
+ // create G (result in mm7)
+ "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1
+ "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t
+ "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t
+ "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1
+ "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0
+ "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1
+ "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0
+ "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0
+
+ // create B (result in mm5)
+ "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1
+ "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1
+ "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1
+ "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0
+ "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1
+ "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0
+ "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0
+
+ // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0
+ "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0
+ "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0
+ // process lower lum
+ "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0
+ "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0
+ "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0
+ "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0
+ "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0
+ "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0
+ "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0
+ "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0
+ "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0
+ "movq %%mm2,(%3)\n" // wrote out ! row1
+
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0
+ "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0
+ "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2
+ "movq %%mm4,8(%3)\n" // wrote out ! row1
+
+ // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb)
+ // this can be done "destructive"
+ "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0
+ "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0
+ "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0
+ "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0
+ "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0
+ "movq %%mm1,(%5)\n" // wrote out ! row2
+ "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2
+ "movq %%mm5,8(%5)\n" // wrote out ! row2
+
+ "addl $4,%2\n" // lum+4
+ "leal 16(%3),%3\n" // row1+16
+ "leal 16(%5),%5\n" // row2+16
+ "addl $2,(%%esp)\n" // cr+2
+ "addl $2,%1\n" // cb+2
+
+ "addl $4,%6\n" // x+4
+ "cmpl %4,%6\n"
+
+ "jl 1b\n"
+ "addl %4,%2\n" // lum += cols
+ "addl %8,%3\n" // row1+= mod
+ "addl %8,%5\n" // row2+= mod
+ "movl $0,%6\n" // x=0
+ "cmpl %7,%2\n"
+ "jl 1b\n"
+
+ "addl $4,%%esp\n" // get rid of the stack slot we reserved.
+ "emms\n" // reset MMX registers.
+ :
+ : "m" (cr), "r"(cb),"r"(lum),
+ "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod),
+ "m"(MMX_0080w),"m"(MMX_VgrnRGB),"m"(MMX_VredRGB),
+ "m"(MMX_FF00w),"m"(MMX_00FFw),"m"(MMX_UgrnRGB),
+ "m"(MMX_UbluRGB)
+ );
+}
+
+void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ Uint16 *row1;
+ Uint16 *row2;
+
+ unsigned char* y = lum +cols*rows; /* Pointer to the end */
+ int x = 0;
+ row1 = (Uint16 *)out; /* 16 bit target */
+ row2 = (Uint16 *)out+cols+mod; /* start of second row */
+ mod = (mod+cols+mod)*2; /* increment for row1 in byte */
+
+ __asm__ __volatile__(
+ // tap dance to workaround the inability to use %%ebx at will...
+ // move one thing to the stack...
+ "pushl $0\n" // save a slot on the stack.
+ "pushl %%ebx\n" // save %%ebx.
+ "movl %0, %%ebx\n" // put the thing in ebx.
+ "movl %%ebx, 4(%%esp)\n" // put the thing in the stack slot.
+ "popl %%ebx\n" // get back %%ebx (the PIC register).
+
+ ".align 8\n"
+ "1:\n"
+ "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0
+ "pxor %%mm7, %%mm7\n"
+ "pushl %%ebx\n"
+ "movl 4(%%esp), %%ebx\n"
+ "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0
+ "popl %%ebx\n"
+
+ "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0
+ "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0
+ "psubw %9, %%mm0\n"
+ "psubw %9, %%mm1\n"
+ "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0
+ "movq %%mm1, %%mm3\n" // Cr
+ "pmullw %10, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0
+ "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0
+ "pmullw %11, %%mm0\n" // Cb2blue
+ "pand %12, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0
+ "pmullw %13, %%mm3\n" // Cr2green
+ "movq (%2), %%mm7\n" // L2
+ "pmullw %14, %%mm1\n" // Cr2red
+ "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1
+ "pmullw %15, %%mm6\n" // lum1
+ "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green
+ "pmullw %15, %%mm7\n" // lum2
+
+ "movq %%mm6, %%mm4\n" // lum1
+ "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0
+ "movq %%mm4, %%mm5\n" // lum1
+ "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0
+ "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0
+ "psraw $6, %%mm4\n" // R1 0 .. 64
+ "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1
+ "psraw $6, %%mm5\n" // G1 - .. +
+ "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1
+ "psraw $6, %%mm6\n" // B1 0 .. 64
+ "packuswb %%mm4, %%mm4\n" // R1 R1
+ "packuswb %%mm5, %%mm5\n" // G1 G1
+ "packuswb %%mm6, %%mm6\n" // B1 B1
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+
+ "pand %16, %%mm4\n"
+ "psllw $3, %%mm5\n" // GREEN 1
+ "punpcklbw %%mm6, %%mm6\n"
+ "pand %17, %%mm5\n"
+ "pand %16, %%mm6\n"
+ "por %%mm5, %%mm4\n" //
+ "psrlw $11, %%mm6\n" // BLUE 1
+ "movq %%mm3, %%mm5\n" // lum2
+ "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1
+ "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1
+ "psraw $6, %%mm3\n" // R2
+ "por %%mm6, %%mm4\n" // MM4
+ "psraw $6, %%mm5\n" // G2
+ "movq (%2, %4), %%mm6\n" // L3 load lum2
+ "psraw $6, %%mm7\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm5, %%mm5\n"
+ "packuswb %%mm7, %%mm7\n"
+ "pand %12, %%mm6\n" // L3
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "pmullw %15, %%mm6\n" // lum3
+ "punpcklbw %%mm7, %%mm7\n"
+ "psllw $3, %%mm5\n" // GREEN 2
+ "pand %16, %%mm7\n"
+ "pand %16, %%mm3\n"
+ "psrlw $11, %%mm7\n" // BLUE 2
+ "pand %17, %%mm5\n"
+ "por %%mm7, %%mm3\n"
+ "movq (%2,%4), %%mm7\n" // L4 load lum2
+ "por %%mm5, %%mm3\n" //
+ "psrlw $8, %%mm7\n" // L4
+ "movq %%mm4, %%mm5\n"
+ "punpcklwd %%mm3, %%mm4\n"
+ "pmullw %15, %%mm7\n" // lum4
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%3)\n" // write row1
+ "movq %%mm5, 8(%3)\n" // write row1
+
+ "movq %%mm6, %%mm4\n" // Lum3
+ "paddw %%mm0, %%mm6\n" // Lum3 +blue
+
+ "movq %%mm4, %%mm5\n" // Lum3
+ "paddw %%mm1, %%mm4\n" // Lum3 +red
+ "paddw %%mm2, %%mm5\n" // Lum3 +green
+ "psraw $6, %%mm4\n"
+ "movq %%mm7, %%mm3\n" // Lum4
+ "psraw $6, %%mm5\n"
+ "paddw %%mm0, %%mm7\n" // Lum4 +blue
+ "psraw $6, %%mm6\n" // Lum3 +blue
+ "movq %%mm3, %%mm0\n" // Lum4
+ "packuswb %%mm4, %%mm4\n"
+ "paddw %%mm1, %%mm3\n" // Lum4 +red
+ "packuswb %%mm5, %%mm5\n"
+ "paddw %%mm2, %%mm0\n" // Lum4 +green
+ "packuswb %%mm6, %%mm6\n"
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "punpcklbw %%mm6, %%mm6\n"
+ "psllw $3, %%mm5\n" // GREEN 3
+ "pand %16, %%mm4\n"
+ "psraw $6, %%mm3\n" // psr 6
+ "psraw $6, %%mm0\n"
+ "pand %16, %%mm6\n" // BLUE
+ "pand %17, %%mm5\n"
+ "psrlw $11, %%mm6\n" // BLUE 3
+ "por %%mm5, %%mm4\n"
+ "psraw $6, %%mm7\n"
+ "por %%mm6, %%mm4\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm0, %%mm0\n"
+ "packuswb %%mm7, %%mm7\n"
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm0, %%mm0\n"
+ "punpcklbw %%mm7, %%mm7\n"
+ "pand %16, %%mm3\n"
+ "pand %16, %%mm7\n" // BLUE
+ "psllw $3, %%mm0\n" // GREEN 4
+ "psrlw $11, %%mm7\n"
+ "pand %17, %%mm0\n"
+ "por %%mm7, %%mm3\n"
+ "por %%mm0, %%mm3\n"
+
+ "movq %%mm4, %%mm5\n"
+
+ "punpcklwd %%mm3, %%mm4\n"
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%5)\n"
+ "movq %%mm5, 8(%5)\n"
+
+ "addl $8, %6\n"
+ "addl $8, %2\n"
+ "addl $4, (%%esp)\n"
+ "addl $4, %1\n"
+ "cmpl %4, %6\n"
+ "leal 16(%3), %3\n"
+ "leal 16(%5),%5\n" // row2+16
+
+ "jl 1b\n"
+ "addl %4, %2\n" // lum += cols
+ "addl %8, %3\n" // row1+= mod
+ "addl %8, %5\n" // row2+= mod
+ "movl $0, %6\n" // x=0
+ "cmpl %7, %2\n"
+ "jl 1b\n"
+ "addl $4, %%esp\n" // get rid of the stack slot we reserved.
+ "emms\n"
+ :
+ : "m" (cr), "r"(cb),"r"(lum),
+ "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod),
+ "m"(MMX_0080w),"m"(MMX_Ugrn565),"m"(MMX_Ublu5x5),
+ "m"(MMX_00FFw),"m"(MMX_Vgrn565),"m"(MMX_Vred5x5),
+ "m"(MMX_Ycoeff),"m"(MMX_red565),"m"(MMX_grn565)
+ );
+}
+
+/* *INDENT-ON* */
+
+#endif /* GCC3 i386 inline assembly */
+
diff --git a/distrib/sdl-1.2.15/src/video/SDL_yuv_sw.c b/distrib/sdl-1.2.15/src/video/SDL_yuv_sw.c
new file mode 100644
index 0000000..c555ce0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_yuv_sw.c
@@ -0,0 +1,1299 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the software implementation of the YUV video overlay support */
+
+/* This code was derived from code carrying the following copyright notices:
+
+ * Copyright (c) 1995 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+ * Copyright (c) 1995 Erik Corry
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+ * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+ * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+ * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+ * Portions of this software Copyright (c) 1995 Brown University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement
+ * is hereby granted, provided that the above copyright notice and the
+ * following two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+ * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "SDL_video.h"
+#include "SDL_cpuinfo.h"
+#include "SDL_stretch_c.h"
+#include "SDL_yuvfuncs.h"
+#include "SDL_yuv_sw_c.h"
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs sw_yuvfuncs = {
+ SDL_LockYUV_SW,
+ SDL_UnlockYUV_SW,
+ SDL_DisplayYUV_SW,
+ SDL_FreeYUV_SW
+};
+
+/* RGB conversion lookup tables */
+struct private_yuvhwdata {
+ SDL_Surface *stretch;
+ SDL_Surface *display;
+ Uint8 *pixels;
+ int *colortab;
+ Uint32 *rgb_2_pix;
+ void (*Display1X)(int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod );
+ void (*Display2X)(int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod );
+
+ /* These are just so we don't have to allocate them separately */
+ Uint16 pitches[3];
+ Uint8 *planes[3];
+};
+
+
+/* The colorspace conversion functions */
+
+#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES
+extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod );
+extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod );
+#endif
+
+static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned short* row1;
+ unsigned short* row2;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row1 = (unsigned short*) out;
+ row2 = row1 + cols + mod;
+ lum2 = lum + cols;
+
+ mod += cols + mod;
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum++;
+ *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum2++;
+ *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int value;
+ unsigned char* row1;
+ unsigned char* row2;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row1 = out;
+ row2 = row1 + cols*3 + mod*3;
+ lum2 = lum + cols;
+
+ mod += cols + mod;
+ mod *= 3;
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row1++ = (value ) & 0xFF;
+ *row1++ = (value >> 8) & 0xFF;
+ *row1++ = (value >> 16) & 0xFF;
+
+ L = *lum++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row1++ = (value ) & 0xFF;
+ *row1++ = (value >> 8) & 0xFF;
+ *row1++ = (value >> 16) & 0xFF;
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row2++ = (value ) & 0xFF;
+ *row2++ = (value >> 8) & 0xFF;
+ *row2++ = (value >> 16) & 0xFF;
+
+ L = *lum2++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row2++ = (value ) & 0xFF;
+ *row2++ = (value >> 8) & 0xFF;
+ *row2++ = (value >> 16) & 0xFF;
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row1;
+ unsigned int* row2;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row1 = (unsigned int*) out;
+ row2 = row1 + cols + mod;
+ lum2 = lum + cols;
+
+ mod += cols + mod;
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ *row1++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum++;
+ *row1++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ *row2++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum2++;
+ *row2++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+/*
+ * In this function I make use of a nasty trick. The tables have the lower
+ * 16 bits replicated in the upper 16. This means I can write ints and get
+ * the horisontal doubling for free (almost).
+ */
+static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row1 = (unsigned int*) out;
+ const int next_row = cols+(mod/2);
+ unsigned int* row2 = row1 + 2*next_row;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ lum2 = lum + cols;
+
+ mod = (next_row * 3) + (mod/2);
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1++;
+
+ L = *lum++;
+ row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1++;
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2++;
+
+ L = *lum2++;
+ row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2++;
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int value;
+ unsigned char* row1 = out;
+ const int next_row = (cols*2 + mod) * 3;
+ unsigned char* row2 = row1 + 2*next_row;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ lum2 = lum + cols;
+
+ mod = next_row*3 + mod*3;
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] =
+ (value ) & 0xFF;
+ row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row1 += 2*3;
+
+ L = *lum++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] =
+ (value ) & 0xFF;
+ row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row1 += 2*3;
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] =
+ (value ) & 0xFF;
+ row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row2 += 2*3;
+
+ L = *lum2++;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] =
+ (value ) & 0xFF;
+ row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row2 += 2*3;
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row1 = (unsigned int*) out;
+ const int next_row = cols*2+mod;
+ unsigned int* row2 = row1 + 2*next_row;
+ unsigned char* lum2;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ lum2 = lum + cols;
+
+ mod = (next_row * 3) + mod;
+
+ y = rows / 2;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ ++cr; ++cb;
+
+ L = *lum++;
+ row1[0] = row1[1] = row1[next_row] = row1[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1 += 2;
+
+ L = *lum++;
+ row1[0] = row1[1] = row1[next_row] = row1[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row1 += 2;
+
+
+ /* Now, do second row. */
+
+ L = *lum2++;
+ row2[0] = row2[1] = row2[next_row] = row2[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2 += 2;
+
+ L = *lum2++;
+ row2[0] = row2[1] = row2[next_row] = row2[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row2 += 2;
+ }
+
+ /*
+ * These values are at the start of the next line, (due
+ * to the ++'s above),but they need to be at the start
+ * of the line after that.
+ */
+ lum += cols;
+ lum2 += cols;
+ row1 += mod;
+ row2 += mod;
+ }
+}
+
+static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned short* row;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row = (unsigned short*) out;
+
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum; lum += 2;
+ *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ }
+
+ row += mod;
+ }
+}
+
+static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int value;
+ unsigned char* row;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row = (unsigned char*) out;
+ mod *= 3;
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row++ = (value ) & 0xFF;
+ *row++ = (value >> 8) & 0xFF;
+ *row++ = (value >> 16) & 0xFF;
+
+ L = *lum; lum += 2;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ *row++ = (value ) & 0xFF;
+ *row++ = (value >> 8) & 0xFF;
+ *row++ = (value >> 16) & 0xFF;
+
+ }
+ row += mod;
+ }
+}
+
+static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ row = (unsigned int*) out;
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ *row++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+ L = *lum; lum += 2;
+ *row++ = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+
+
+ }
+ row += mod;
+ }
+}
+
+/*
+ * In this function I make use of a nasty trick. The tables have the lower
+ * 16 bits replicated in the upper 16. This means I can write ints and get
+ * the horisontal doubling for free (almost).
+ */
+static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row = (unsigned int*) out;
+ const int next_row = cols+(mod/2);
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row++;
+
+ L = *lum; lum += 2;
+ row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row++;
+
+ }
+ row += next_row;
+ }
+}
+
+static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int value;
+ unsigned char* row = out;
+ const int next_row = (cols*2 + mod) * 3;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] =
+ (value ) & 0xFF;
+ row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row += 2*3;
+
+ L = *lum; lum += 2;
+ value = (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] =
+ (value ) & 0xFF;
+ row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] =
+ (value >> 8) & 0xFF;
+ row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] =
+ (value >> 16) & 0xFF;
+ row += 2*3;
+
+ }
+ row += next_row;
+ }
+}
+
+static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
+ unsigned char *lum, unsigned char *cr,
+ unsigned char *cb, unsigned char *out,
+ int rows, int cols, int mod )
+{
+ unsigned int* row = (unsigned int*) out;
+ const int next_row = cols*2+mod;
+ int x, y;
+ int cr_r;
+ int crb_g;
+ int cb_b;
+ int cols_2 = cols / 2;
+ mod+=mod;
+ y = rows;
+ while( y-- )
+ {
+ x = cols_2;
+ while( x-- )
+ {
+ register int L;
+
+ cr_r = 0*768+256 + colortab[ *cr + 0*256 ];
+ crb_g = 1*768+256 + colortab[ *cr + 1*256 ]
+ + colortab[ *cb + 2*256 ];
+ cb_b = 2*768+256 + colortab[ *cb + 3*256 ];
+ cr += 4; cb += 4;
+
+ L = *lum; lum += 2;
+ row[0] = row[1] = row[next_row] = row[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row += 2;
+
+ L = *lum; lum += 2;
+ row[0] = row[1] = row[next_row] = row[next_row+1] =
+ (rgb_2_pix[ L + cr_r ] |
+ rgb_2_pix[ L + crb_g ] |
+ rgb_2_pix[ L + cb_b ]);
+ row += 2;
+
+
+ }
+
+ row += next_row;
+ }
+}
+
+/*
+ * How many 1 bits are there in the Uint32.
+ * Low performance, do not call often.
+ */
+static int number_of_bits_set( Uint32 a )
+{
+ if(!a) return 0;
+ if(a & 1) return 1 + number_of_bits_set(a >> 1);
+ return(number_of_bits_set(a >> 1));
+}
+
+/*
+ * How many 0 bits are there at least significant end of Uint32.
+ * Low performance, do not call often.
+ */
+static int free_bits_at_bottom( Uint32 a )
+{
+ /* assume char is 8 bits */
+ if(!a) return sizeof(Uint32) * 8;
+ if(((Sint32)a) & 1l) return 0;
+ return 1 + free_bits_at_bottom ( a >> 1);
+}
+
+
+SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+ SDL_Overlay *overlay;
+ struct private_yuvhwdata *swdata;
+ int *Cr_r_tab;
+ int *Cr_g_tab;
+ int *Cb_g_tab;
+ int *Cb_b_tab;
+ Uint32 *r_2_pix_alloc;
+ Uint32 *g_2_pix_alloc;
+ Uint32 *b_2_pix_alloc;
+ int i;
+ int CR, CB;
+ Uint32 Rmask, Gmask, Bmask;
+
+ /* Only RGB packed pixel conversion supported */
+ if ( (display->format->BytesPerPixel != 2) &&
+ (display->format->BytesPerPixel != 3) &&
+ (display->format->BytesPerPixel != 4) ) {
+ SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces");
+ return(NULL);
+ }
+
+ /* Verify that we support the format */
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ case SDL_YUY2_OVERLAY:
+ case SDL_UYVY_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format");
+ return(NULL);
+ }
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
+ if ( overlay == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(overlay, 0, (sizeof *overlay));
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &sw_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ swdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *swdata);
+ overlay->hwdata = swdata;
+ if ( swdata == NULL ) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ swdata->stretch = NULL;
+ swdata->display = display;
+ swdata->pixels = (Uint8 *) SDL_malloc(width*height*2);
+ swdata->colortab = (int *)SDL_malloc(4*256*sizeof(int));
+ Cr_r_tab = &swdata->colortab[0*256];
+ Cr_g_tab = &swdata->colortab[1*256];
+ Cb_g_tab = &swdata->colortab[2*256];
+ Cb_b_tab = &swdata->colortab[3*256];
+ swdata->rgb_2_pix = (Uint32 *)SDL_malloc(3*768*sizeof(Uint32));
+ r_2_pix_alloc = &swdata->rgb_2_pix[0*768];
+ g_2_pix_alloc = &swdata->rgb_2_pix[1*768];
+ b_2_pix_alloc = &swdata->rgb_2_pix[2*768];
+ if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+
+ /* Generate the tables for the display surface */
+ for (i=0; i<256; i++) {
+ /* Gamma correction (luminescence table) and chroma correction
+ would be done here. See the Berkeley mpeg_play sources.
+ */
+ CB = CR = (i-128);
+ Cr_r_tab[i] = (int) ( (0.419/0.299) * CR);
+ Cr_g_tab[i] = (int) (-(0.299/0.419) * CR);
+ Cb_g_tab[i] = (int) (-(0.114/0.331) * CB);
+ Cb_b_tab[i] = (int) ( (0.587/0.331) * CB);
+ }
+
+ /*
+ * Set up entries 0-255 in rgb-to-pixel value tables.
+ */
+ Rmask = display->format->Rmask;
+ Gmask = display->format->Gmask;
+ Bmask = display->format->Bmask;
+ for ( i=0; i<256; ++i ) {
+ r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask));
+ r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask);
+ g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask));
+ g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask);
+ b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask));
+ b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask);
+ }
+
+ /*
+ * If we have 16-bit output depth, then we double the value
+ * in the top word. This means that we can write out both
+ * pixels in the pixel doubling mode with one op. It is
+ * harmless in the normal case as storing a 32-bit value
+ * through a short pointer will lose the top bits anyway.
+ */
+ if( display->format->BytesPerPixel == 2 ) {
+ for ( i=0; i<256; ++i ) {
+ r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16;
+ g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16;
+ b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16;
+ }
+ }
+
+ /*
+ * Spread out the values we have to the rest of the array so that
+ * we do not need to check for overflow.
+ */
+ for ( i=0; i<256; ++i ) {
+ r_2_pix_alloc[i] = r_2_pix_alloc[256];
+ r_2_pix_alloc[i+512] = r_2_pix_alloc[511];
+ g_2_pix_alloc[i] = g_2_pix_alloc[256];
+ g_2_pix_alloc[i+512] = g_2_pix_alloc[511];
+ b_2_pix_alloc[i] = b_2_pix_alloc[256];
+ b_2_pix_alloc[i+512] = b_2_pix_alloc[511];
+ }
+
+ /* You have chosen wisely... */
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ if ( display->format->BytesPerPixel == 2 ) {
+#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES
+ /* inline assembly functions */
+ if ( SDL_HasMMX() && (Rmask == 0xF800) &&
+ (Gmask == 0x07E0) &&
+ (Bmask == 0x001F) &&
+ (width & 15) == 0) {
+/*printf("Using MMX 16-bit 565 dither\n");*/
+ swdata->Display1X = Color565DitherYV12MMX1X;
+ } else {
+/*printf("Using C 16-bit dither\n");*/
+ swdata->Display1X = Color16DitherYV12Mod1X;
+ }
+#else
+ swdata->Display1X = Color16DitherYV12Mod1X;
+#endif
+ swdata->Display2X = Color16DitherYV12Mod2X;
+ }
+ if ( display->format->BytesPerPixel == 3 ) {
+ swdata->Display1X = Color24DitherYV12Mod1X;
+ swdata->Display2X = Color24DitherYV12Mod2X;
+ }
+ if ( display->format->BytesPerPixel == 4 ) {
+#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES
+ /* inline assembly functions */
+ if ( SDL_HasMMX() && (Rmask == 0x00FF0000) &&
+ (Gmask == 0x0000FF00) &&
+ (Bmask == 0x000000FF) &&
+ (width & 15) == 0) {
+/*printf("Using MMX 32-bit dither\n");*/
+ swdata->Display1X = ColorRGBDitherYV12MMX1X;
+ } else {
+/*printf("Using C 32-bit dither\n");*/
+ swdata->Display1X = Color32DitherYV12Mod1X;
+ }
+#else
+ swdata->Display1X = Color32DitherYV12Mod1X;
+#endif
+ swdata->Display2X = Color32DitherYV12Mod2X;
+ }
+ break;
+ case SDL_YUY2_OVERLAY:
+ case SDL_UYVY_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ if ( display->format->BytesPerPixel == 2 ) {
+ swdata->Display1X = Color16DitherYUY2Mod1X;
+ swdata->Display2X = Color16DitherYUY2Mod2X;
+ }
+ if ( display->format->BytesPerPixel == 3 ) {
+ swdata->Display1X = Color24DitherYUY2Mod1X;
+ swdata->Display2X = Color24DitherYUY2Mod2X;
+ }
+ if ( display->format->BytesPerPixel == 4 ) {
+ swdata->Display1X = Color32DitherYUY2Mod1X;
+ swdata->Display2X = Color32DitherYUY2Mod2X;
+ }
+ break;
+ default:
+ /* We should never get here (caught above) */
+ break;
+ }
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->pitches = swdata->pitches;
+ overlay->pixels = swdata->planes;
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ overlay->pitches[0] = overlay->w;
+ overlay->pitches[1] = overlay->pitches[0] / 2;
+ overlay->pitches[2] = overlay->pitches[0] / 2;
+ overlay->pixels[0] = swdata->pixels;
+ overlay->pixels[1] = overlay->pixels[0] +
+ overlay->pitches[0] * overlay->h;
+ overlay->pixels[2] = overlay->pixels[1] +
+ overlay->pitches[1] * overlay->h / 2;
+ overlay->planes = 3;
+ break;
+ case SDL_YUY2_OVERLAY:
+ case SDL_UYVY_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ overlay->pitches[0] = overlay->w*2;
+ overlay->pixels[0] = swdata->pixels;
+ overlay->planes = 1;
+ break;
+ default:
+ /* We should never get here (caught above) */
+ break;
+ }
+
+ /* We're all done.. */
+ return(overlay);
+}
+
+int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay)
+{
+ return(0);
+}
+
+void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay)
+{
+ return;
+}
+
+int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
+{
+ struct private_yuvhwdata *swdata;
+ int stretch;
+ int scale_2x;
+ SDL_Surface *display;
+ Uint8 *lum, *Cr, *Cb;
+ Uint8 *dstp;
+ int mod;
+
+ swdata = overlay->hwdata;
+ stretch = 0;
+ scale_2x = 0;
+ if ( src->x || src->y || src->w < overlay->w || src->h < overlay->h ) {
+ /* The source rectangle has been clipped.
+ Using a scratch surface is easier than adding clipped
+ source support to all the blitters, plus that would
+ slow them down in the general unclipped case.
+ */
+ stretch = 1;
+ } else if ( (src->w != dst->w) || (src->h != dst->h) ) {
+ if ( (dst->w == 2*src->w) &&
+ (dst->h == 2*src->h) ) {
+ scale_2x = 1;
+ } else {
+ stretch = 1;
+ }
+ }
+ if ( stretch ) {
+ if ( ! swdata->stretch ) {
+ display = swdata->display;
+ swdata->stretch = SDL_CreateRGBSurface(
+ SDL_SWSURFACE,
+ overlay->w, overlay->h,
+ display->format->BitsPerPixel,
+ display->format->Rmask,
+ display->format->Gmask,
+ display->format->Bmask, 0);
+ if ( ! swdata->stretch ) {
+ return(-1);
+ }
+ }
+ display = swdata->stretch;
+ } else {
+ display = swdata->display;
+ }
+ switch (overlay->format) {
+ case SDL_YV12_OVERLAY:
+ lum = overlay->pixels[0];
+ Cr = overlay->pixels[1];
+ Cb = overlay->pixels[2];
+ break;
+ case SDL_IYUV_OVERLAY:
+ lum = overlay->pixels[0];
+ Cr = overlay->pixels[2];
+ Cb = overlay->pixels[1];
+ break;
+ case SDL_YUY2_OVERLAY:
+ lum = overlay->pixels[0];
+ Cr = lum + 3;
+ Cb = lum + 1;
+ break;
+ case SDL_UYVY_OVERLAY:
+ lum = overlay->pixels[0]+1;
+ Cr = lum + 1;
+ Cb = lum - 1;
+ break;
+ case SDL_YVYU_OVERLAY:
+ lum = overlay->pixels[0];
+ Cr = lum + 1;
+ Cb = lum + 3;
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format in blit");
+ return(-1);
+ }
+ if ( SDL_MUSTLOCK(display) ) {
+ if ( SDL_LockSurface(display) < 0 ) {
+ return(-1);
+ }
+ }
+ if ( stretch ) {
+ dstp = (Uint8 *)swdata->stretch->pixels;
+ } else {
+ dstp = (Uint8 *)display->pixels
+ + dst->x * display->format->BytesPerPixel
+ + dst->y * display->pitch;
+ }
+ mod = (display->pitch / display->format->BytesPerPixel);
+
+ if ( scale_2x ) {
+ mod -= (overlay->w * 2);
+ swdata->Display2X(swdata->colortab, swdata->rgb_2_pix,
+ lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
+ } else {
+ mod -= overlay->w;
+ swdata->Display1X(swdata->colortab, swdata->rgb_2_pix,
+ lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
+ }
+ if ( SDL_MUSTLOCK(display) ) {
+ SDL_UnlockSurface(display);
+ }
+ if ( stretch ) {
+ display = swdata->display;
+ SDL_SoftStretch(swdata->stretch, src, display, dst);
+ }
+ SDL_UpdateRects(display, 1, dst);
+
+ return(0);
+}
+
+void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay)
+{
+ struct private_yuvhwdata *swdata;
+
+ swdata = overlay->hwdata;
+ if ( swdata ) {
+ if ( swdata->stretch ) {
+ SDL_FreeSurface(swdata->stretch);
+ }
+ if ( swdata->pixels ) {
+ SDL_free(swdata->pixels);
+ }
+ if ( swdata->colortab ) {
+ SDL_free(swdata->colortab);
+ }
+ if ( swdata->rgb_2_pix ) {
+ SDL_free(swdata->rgb_2_pix);
+ }
+ SDL_free(swdata);
+ overlay->hwdata = NULL;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/SDL_yuv_sw_c.h b/distrib/sdl-1.2.15/src/video/SDL_yuv_sw_c.h
new file mode 100644
index 0000000..5aea3a5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_yuv_sw_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+
+/* This is the software implementation of the YUV video overlay support */
+
+extern SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay);
+
+extern void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay);
+
+extern int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+
+extern void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay);
diff --git a/distrib/sdl-1.2.15/src/video/SDL_yuvfuncs.h b/distrib/sdl-1.2.15/src/video/SDL_yuvfuncs.h
new file mode 100644
index 0000000..cb496b6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/SDL_yuvfuncs.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the definition of the YUV video surface function structure */
+
+#include "SDL_video.h"
+#include "SDL_sysvideo.h"
+
+#ifndef _THIS
+#define _THIS SDL_VideoDevice *_this
+#endif
+struct private_yuvhwfuncs {
+ int (*Lock)(_THIS, SDL_Overlay *overlay);
+ void (*Unlock)(_THIS, SDL_Overlay *overlay);
+ int (*Display)(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+ void (*FreeHW)(_THIS, SDL_Overlay *overlay);
+};
diff --git a/distrib/sdl-1.2.15/src/video/Xext/README b/distrib/sdl-1.2.15/src/video/Xext/README
new file mode 100644
index 0000000..a16ea68
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/README
@@ -0,0 +1,10 @@
+
+The reason these libraries are built outside of the standard XFree86
+tree is so that they can be linked as shared object code directly into
+SDL without causing any symbol collisions with code in the application.
+
+You can't link static library code into shared libraries on non-x86
+Linux platforms. Since these libraries haven't become standard yet,
+we'll just include them directly.
+
+These sources are synchronized with XFree86 4.2.1
diff --git a/distrib/sdl-1.2.15/src/video/Xext/XME/xme.c b/distrib/sdl-1.2.15/src/video/Xext/XME/xme.c
new file mode 100644
index 0000000..2cead35
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/XME/xme.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright 1993-2001 by Xi Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * Please see the LICENSE file accompanying this distribution for licensing
+ * information.
+ *
+ * Please send any bug fixes and modifications to src@xig.com.
+ *
+ * $XiGId: xme.c,v 1.2 2001/11/30 21:56:59 jon Exp $
+ *
+ */
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include <X11/Xthreads.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "../extensions/Xext.h"
+#include "../extensions/extutil.h"
+
+/*****************************************************************************/
+
+
+#define XIGMISC_PROTOCOL_NAME "XiG-SUNDRY-NONSTANDARD"
+#define XIGMISC_MAJOR_VERSION 2
+#define XIGMISC_MINOR_VERSION 0
+
+#define XiGMiscNumberEvents 0
+
+#define X_XiGMiscQueryVersion 0
+#define X_XiGMiscQueryViews 1
+#define X_XiGMiscQueryResolutions 2
+#define X_XiGMiscChangeResolution 3
+#define X_XiGMiscFullScreen 4
+
+#define sz_xXiGMiscQueryVersionReq 8
+#define sz_xXiGMiscQueryViewsReq 8
+#define sz_xXiGMiscQueryResolutionsReq 8
+#define sz_xXiGMiscChangeResolutionReq 16
+#define sz_xXiGMiscFullScreenReq 16
+
+#define sz_xXiGMiscQueryVersionReply 32
+#define sz_xXiGMiscQueryViewsReply 32
+#define sz_xXiGMiscQueryResolutionsReply 32
+#define sz_xXiGMiscQueryFullScreenReply 32
+
+/*******************************************************************/
+
+typedef struct {
+ CARD8 reqType; /* always codes->major_opcode */
+ CARD8 xigmiscReqType; /* always X_XiGMiscQueryVersion */
+ CARD16 length;
+ CARD16 major;
+ CARD16 minor;
+} xXiGMiscQueryVersionReq;
+
+typedef struct {
+ CARD8 reqType; /* always codes->major_opcode */
+ CARD8 xigmiscReqType; /* always X_XiGMiscQueryViews */
+ CARD16 length;
+ CARD8 screen;
+ CARD8 pad0;
+ CARD16 pad1;
+} xXiGMiscQueryViewsReq;
+
+typedef struct {
+ CARD8 reqType; /* always codes->major_opcode */
+ CARD8 xigmiscReqType; /* always X_XiGMiscQueryResolutions */
+ CARD16 length;
+ CARD8 screen;
+ CARD8 view;
+ CARD16 pad0;
+} xXiGMiscQueryResolutionsReq;
+
+typedef struct {
+ CARD8 reqType; /* always codes->major_opcode */
+ CARD8 xigmiscReqType; /* always X_XiGMiscChangeResolution */
+ CARD16 length;
+ CARD8 screen;
+ CARD8 view;
+ CARD16 pad0;
+ CARD16 width;
+ CARD16 height;
+ INT32 refresh;
+} xXiGMiscChangeResolutionReq;
+
+typedef struct {
+ CARD8 reqType; /* always codes->major_opcode */
+ CARD8 xigmiscReqType; /* always X_XiGMiscFullScreen */
+ CARD16 length;
+ CARD8 screen;
+ CARD8 pad0;
+ CARD16 pad1;
+ CARD32 window;
+ CARD32 cmap;
+} xXiGMiscFullScreenReq;
+
+/*******************************************************************/
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 major;
+ CARD16 minor;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xXiGMiscQueryVersionReply;
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 nviews;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xXiGMiscQueryViewsReply;
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 pad0;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 active;
+ CARD16 nresolutions;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+} xXiGMiscQueryResolutionsReply;
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL success;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD32 pad1;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} xXiGMiscFullScreenReply;
+
+/*******************************************************************/
+
+typedef struct {
+ INT16 x;
+ INT16 y;
+ CARD16 w;
+ CARD16 h;
+} XiGMiscViewInfo;
+
+typedef struct {
+ CARD16 width;
+ CARD16 height;
+ INT32 refresh;
+} XiGMiscResolutionInfo;
+
+/*****************************************************************************/
+
+static XExtensionInfo *xigmisc_info = NULL;
+static char *xigmisc_extension_name = XIGMISC_PROTOCOL_NAME;
+
+#define XiGMiscCheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xigmisc_extension_name, val)
+#define XiGMiscSimpleCheckExtension(dpy,i) \
+ XextSimpleCheckExtension (dpy, i, xigmisc_extension_name)
+
+#if defined(__STDC__) && !defined(UNIXCPP)
+#define XiGMiscGetReq(name,req,info) GetReq (name, req); \
+ req->reqType = info->codes->major_opcode; \
+ req->xigmiscReqType = X_##name;
+
+#define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \
+ req->reqType = info->codes->major_opcode; \
+ req->xigmicReqType = X_##name;
+#else
+#define XiGMiscGetReq(name,req,info) GetReq (name, req); \
+ req->reqType = info->codes->major_opcode; \
+ req->xigmiscReqType = X_/**/name;
+#define XiGMiscGetReqExtra(name,n,req,info) GetReqExtra (name, n, req); \
+ req->reqType = info->codes->major_opcode; \
+ req->xigmiscReqType = X_/**/name;
+#endif
+
+
+
+/*
+ * find_display - locate the display info block
+ */
+static int XiGMiscCloseDisplay();
+
+static XExtensionHooks xigmisc_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ XiGMiscCloseDisplay, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+
+static XEXT_GENERATE_CLOSE_DISPLAY (XiGMiscCloseDisplay, xigmisc_info)
+
+static XEXT_GENERATE_FIND_DISPLAY (XiGMiscFindDisplay, xigmisc_info,
+ xigmisc_extension_name,
+ &xigmisc_extension_hooks, XiGMiscNumberEvents, NULL)
+
+
+/*****************************************************************************/
+
+Bool XiGMiscQueryVersion(Display *dpy, int *major, int *minor)
+{
+ int opcode, event, error;
+ xXiGMiscQueryVersionReq *req;
+ xXiGMiscQueryVersionReply rep;
+ XExtDisplayInfo *info = XiGMiscFindDisplay(dpy);
+
+ if (!XQueryExtension(dpy, XIGMISC_PROTOCOL_NAME, &opcode, &event, &error))
+ return xFalse;
+
+ XiGMiscCheckExtension(dpy, info, xFalse);
+
+ LockDisplay (dpy);
+ XiGMiscGetReq (XiGMiscQueryVersion, req, info);
+
+ req->major = XIGMISC_MAJOR_VERSION;
+ req->minor = XIGMISC_MINOR_VERSION;
+
+ if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return xFalse;
+ }
+
+ *major = rep.major;
+ *minor = rep.minor;
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return xTrue;
+}
+
+int XiGMiscQueryViews(Display *dpy, int screen, XiGMiscViewInfo **pviews)
+{
+ int n, size;
+ XiGMiscViewInfo *views;
+ xXiGMiscQueryViewsReq *req;
+ xXiGMiscQueryViewsReply rep;
+ XExtDisplayInfo *info = XiGMiscFindDisplay(dpy);
+ XiGMiscCheckExtension(dpy, info, 0);
+
+ LockDisplay (dpy);
+ XiGMiscGetReq (XiGMiscQueryViews, req, info);
+ req->screen = screen;
+
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ n = rep.nviews;
+
+ if (n > 0) {
+ size = sizeof(XiGMiscViewInfo) * n;
+ views = (XiGMiscViewInfo*)Xmalloc(size);
+ if (!views) {
+ _XEatData(dpy, (unsigned long)size);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ _XReadPad(dpy, (void*)views, size);
+
+ *pviews = views;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return n;
+}
+
+int XiGMiscQueryResolutions(Display *dpy, int screen, int view, int *pactive, XiGMiscResolutionInfo **presolutions)
+{
+ int n, size;
+ XiGMiscResolutionInfo *resolutions;
+ xXiGMiscQueryResolutionsReq *req;
+ xXiGMiscQueryResolutionsReply rep;
+ XExtDisplayInfo *info = XiGMiscFindDisplay(dpy);
+ XiGMiscCheckExtension(dpy, info, 0);
+
+ LockDisplay (dpy);
+ XiGMiscGetReq (XiGMiscQueryResolutions, req, info);
+ req->screen = screen;
+ req->view = view;
+
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ n = rep.nresolutions;
+
+ if (n > 0) {
+ size = sizeof(XiGMiscResolutionInfo) * n;
+ resolutions = (XiGMiscResolutionInfo*)Xmalloc(size);
+ if (!resolutions) {
+ _XEatData(dpy, (unsigned long)size);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return 0;
+ }
+
+ _XReadPad(dpy, (void*)resolutions, size);
+
+ *presolutions = resolutions;
+ *pactive = rep.active;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return n;
+}
+
+void XiGMiscChangeResolution(Display *dpy, int screen, int view, int width, int height, int refresh)
+{
+ xXiGMiscChangeResolutionReq *req;
+ XExtDisplayInfo *info = XiGMiscFindDisplay(dpy);
+
+ XiGMiscSimpleCheckExtension(dpy, info);
+
+ LockDisplay (dpy);
+ XiGMiscGetReq (XiGMiscChangeResolution, req, info);
+ req->screen = screen;
+ req->view = view;
+ req->width = width;
+ req->height = height;
+ req->refresh = refresh;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+
+Bool XiGMiscFullScreen(Display *dpy, int screen, XID window, XID cmap)
+{
+ xXiGMiscFullScreenReq *req;
+ xXiGMiscFullScreenReply rep;
+ XExtDisplayInfo *info = XiGMiscFindDisplay(dpy);
+
+ XiGMiscCheckExtension(dpy, info, xFalse);
+
+ LockDisplay (dpy);
+ XiGMiscGetReq (XiGMiscFullScreen, req, info);
+ req->screen = screen;
+ req->pad0 = 0;
+ req->pad1 = 0;
+ req->window = window;
+ req->cmap = cmap;
+
+ if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return xFalse;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (rep.success ? xTrue : xFalse);
+}
+
+
+/* SDL addition from Ryan: free memory used by xme. */
+void XiGMiscDestroy(void)
+{
+ if (xigmisc_info) {
+ XextDestroyExtension(xigmisc_info);
+ xigmisc_info = NULL;
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xinerama/Xinerama.c b/distrib/sdl-1.2.15/src/video/Xext/Xinerama/Xinerama.c
new file mode 100644
index 0000000..4ff42eb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xinerama/Xinerama.c
@@ -0,0 +1,324 @@
+/* $Xorg: XPanoramiX.c,v 1.4 2000/08/17 19:45:51 cpqbld Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+/* $XFree86: xc/lib/Xinerama/Xinerama.c,v 1.2 2001/07/23 17:20:28 dawes Exp $ */
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include <X11/Xutil.h>
+#include "../extensions/Xext.h"
+#include "../extensions/extutil.h" /* in ../include */
+#include "../extensions/panoramiXext.h"
+#include "../extensions/panoramiXproto.h" /* in ../include */
+#include "../extensions/Xinerama.h"
+
+static XExtensionInfo _panoramiX_ext_info_data;
+static XExtensionInfo *panoramiX_ext_info = &_panoramiX_ext_info_data;
+static /* const */ char *panoramiX_extension_name = PANORAMIX_PROTOCOL_NAME;
+
+#define PanoramiXCheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, panoramiX_extension_name, val)
+#define PanoramiXSimpleCheckExtension(dpy,i) \
+ XextSimpleCheckExtension (dpy, i, panoramiX_extension_name)
+
+static int close_display();
+static /* const */ XExtensionHooks panoramiX_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, panoramiX_ext_info,
+ panoramiX_extension_name,
+ &panoramiX_extension_hooks,
+ 0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, panoramiX_ext_info)
+
+
+
+/****************************************************************************
+ * *
+ * PanoramiX public interfaces *
+ * *
+ ****************************************************************************/
+
+Bool SDL_NAME(XPanoramiXQueryExtension) (
+ Display *dpy,
+ int *event_basep,
+ int *error_basep
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+
+Status SDL_NAME(XPanoramiXQueryVersion)(
+ Display *dpy,
+ int *major_versionp,
+ int *minor_versionp
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xPanoramiXQueryVersionReply rep;
+ register xPanoramiXQueryVersionReq *req;
+
+ PanoramiXCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (PanoramiXQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_PanoramiXQueryVersion;
+ req->clientMajor = PANORAMIX_MAJOR_VERSION;
+ req->clientMinor = PANORAMIX_MINOR_VERSION;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ *major_versionp = rep.majorVersion;
+ *minor_versionp = rep.minorVersion;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 1;
+}
+
+SDL_NAME(XPanoramiXInfo) *SDL_NAME(XPanoramiXAllocInfo)(void)
+{
+ return (SDL_NAME(XPanoramiXInfo) *) Xmalloc (sizeof (SDL_NAME(XPanoramiXInfo)));
+}
+
+Status SDL_NAME(XPanoramiXGetState) (
+ Display *dpy,
+ Drawable drawable,
+ SDL_NAME(XPanoramiXInfo) *panoramiX_info
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xPanoramiXGetStateReply rep;
+ register xPanoramiXGetStateReq *req;
+
+ PanoramiXCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (PanoramiXGetState, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_PanoramiXGetState;
+ req->window = drawable;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ panoramiX_info->window = rep.window;
+ panoramiX_info->State = rep.state;
+ return 1;
+}
+
+Status SDL_NAME(XPanoramiXGetScreenCount) (
+ Display *dpy,
+ Drawable drawable,
+ SDL_NAME(XPanoramiXInfo) *panoramiX_info
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xPanoramiXGetScreenCountReply rep;
+ register xPanoramiXGetScreenCountReq *req;
+
+ PanoramiXCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (PanoramiXGetScreenCount, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_PanoramiXGetScreenCount;
+ req->window = drawable;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ panoramiX_info->window = rep.window;
+ panoramiX_info->ScreenCount = rep.ScreenCount;
+ return 1;
+}
+
+Status SDL_NAME(XPanoramiXGetScreenSize) (
+ Display *dpy,
+ Drawable drawable,
+ int screen_num,
+ SDL_NAME(XPanoramiXInfo) *panoramiX_info
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xPanoramiXGetScreenSizeReply rep;
+ register xPanoramiXGetScreenSizeReq *req;
+
+ PanoramiXCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (PanoramiXGetScreenSize, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_PanoramiXGetScreenSize;
+ req->window = drawable;
+ req->screen = screen_num; /* need to define */
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ panoramiX_info->window = rep.window;
+ panoramiX_info->screen = rep.screen;
+ panoramiX_info->width = rep.width;
+ panoramiX_info->height = rep.height;
+ return 1;
+}
+
+/*******************************************************************\
+ Alternate interface to make up for shortcomings in the original,
+ namely, the omission of the screen origin. The new interface is
+ in the "Xinerama" namespace instead of "PanoramiX".
+\*******************************************************************/
+
+Bool SDL_NAME(XineramaQueryExtension) (
+ Display *dpy,
+ int *event_base,
+ int *error_base
+)
+{
+ return SDL_NAME(XPanoramiXQueryExtension)(dpy, event_base, error_base);
+}
+
+Status SDL_NAME(XineramaQueryVersion)(
+ Display *dpy,
+ int *major,
+ int *minor
+)
+{
+ return SDL_NAME(XPanoramiXQueryVersion)(dpy, major, minor);
+}
+
+Bool SDL_NAME(XineramaIsActive)(Display *dpy)
+{
+ xXineramaIsActiveReply rep;
+ xXineramaIsActiveReq *req;
+ XExtDisplayInfo *info = find_display (dpy);
+
+ if(!XextHasExtension(info))
+ return False; /* server doesn't even have the extension */
+
+ LockDisplay (dpy);
+ GetReq (XineramaIsActive, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_XineramaIsActive;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return rep.state;
+}
+
+#include <stdio.h>
+
+SDL_NAME(XineramaScreenInfo) *
+SDL_NAME(XineramaQueryScreens)(
+ Display *dpy,
+ int *number
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXineramaQueryScreensReply rep;
+ xXineramaQueryScreensReq *req;
+ SDL_NAME(XineramaScreenInfo) *scrnInfo = NULL;
+
+ PanoramiXCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (XineramaQueryScreens, req);
+ req->reqType = info->codes->major_opcode;
+ req->panoramiXReqType = X_XineramaQueryScreens;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ if(rep.number) {
+ if((scrnInfo = Xmalloc(sizeof(SDL_NAME(XineramaScreenInfo)) * rep.number))) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < rep.number; i++) {
+ _XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
+ scrnInfo[i].screen_number = i;
+ scrnInfo[i].x_org = scratch.x_org;
+ scrnInfo[i].y_org = scratch.y_org;
+ scrnInfo[i].width = scratch.width;
+ scrnInfo[i].height = scratch.height;
+ }
+
+ *number = rep.number;
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return scrnInfo;
+}
+
+
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xv/Xv.c b/distrib/sdl-1.2.15/src/video/Xext/Xv/Xv.c
new file mode 100644
index 0000000..7147b9e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xv/Xv.c
@@ -0,0 +1,1151 @@
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/lib/Xv/Xv.c,v 1.15 2001/05/11 08:23:22 alanh Exp $ */
+/*
+** File:
+**
+** Xv.c --- Xv library extension module.
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 26.06.91 Carver
+** - changed XvFreeAdaptors to XvFreeAdaptorInfo
+** - changed XvFreeEncodings to XvFreeEncodingInfo
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 240.01.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#include <stdio.h>
+#include "Xvlibint.h"
+#include "../extensions/Xext.h"
+#include <X11/extensions/XShm.h>
+#include "../extensions/extutil.h"
+
+static XExtensionInfo _xv_info_data;
+static XExtensionInfo *xv_info = &_xv_info_data;
+static char *xv_extension_name = XvName;
+
+#define XvCheckExtension(dpy, i, val) \
+ XextCheckExtension(dpy, i, xv_extension_name, val)
+
+static char *xv_error_string();
+static int xv_close_display();
+static Bool xv_wire_to_event();
+
+static XExtensionHooks xv_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xv_close_display, /* close_display */
+ xv_wire_to_event, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ xv_error_string /* error_string */
+};
+
+
+static char *xv_error_list[] =
+{
+ "BadPort", /* XvBadPort */
+ "BadEncoding", /* XvBadEncoding */
+ "BadControl" /* XvBadControl */
+};
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
+
+
+static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
+ xv_extension_name,
+ &xv_extension_hooks,
+ XvNumEvents, NULL)
+
+
+static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
+ XvNumErrors, xv_error_list)
+
+
+int
+SDL_NAME(XvQueryExtension)(
+ Display *dpy,
+ unsigned int *p_version,
+ unsigned int *p_revision,
+ unsigned int *p_requestBase,
+ unsigned int *p_eventBase,
+ unsigned int *p_errorBase
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryExtensionReq *req;
+ xvQueryExtensionReply rep;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryExtension, req);
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return XvBadExtension;
+ }
+
+ *p_version = rep.version;
+ *p_revision = rep.revision;
+ *p_requestBase = info->codes->major_opcode;
+ *p_eventBase = info->codes->first_event;
+ *p_errorBase = info->codes->first_error;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvQueryAdaptors)(
+ Display *dpy,
+ Window window,
+ unsigned int *p_nAdaptors,
+ SDL_NAME(XvAdaptorInfo) **p_pAdaptors
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryAdaptorsReq *req;
+ xvQueryAdaptorsReply rep;
+ int size,ii,jj;
+ char *name;
+ SDL_NAME(XvAdaptorInfo) *pas, *pa;
+ SDL_NAME(XvFormat) *pfs, *pf;
+ char *buffer;
+ union
+ {
+ char *buffer;
+ char *string;
+ xvAdaptorInfo *pa;
+ xvFormat *pf;
+ } u;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryAdaptors, req);
+ req->window = window;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadReply);
+ }
+
+ size = rep.length << 2;
+ if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+ _XRead (dpy, buffer, size);
+
+ u.buffer = buffer;
+
+ /* GET INPUT ADAPTORS */
+
+ if (rep.num_adaptors == 0) {
+ pas = NULL;
+ } else {
+ size = rep.num_adaptors*sizeof(SDL_NAME(XvAdaptorInfo));
+ if ((pas=(SDL_NAME(XvAdaptorInfo) *)Xmalloc(size))==NULL) {
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+ }
+
+ /* INIT ADAPTOR FIELDS */
+
+ pa = pas;
+ for (ii=0; ii<rep.num_adaptors; ii++) {
+ pa->num_adaptors = 0;
+ pa->name = (char *)NULL;
+ pa->formats = (SDL_NAME(XvFormat) *)NULL;
+ pa++;
+ }
+
+ pa = pas;
+ for (ii=0; ii<rep.num_adaptors; ii++) {
+ pa->type = u.pa->type;
+ pa->base_id = u.pa->base_id;
+ pa->num_ports = u.pa->num_ports;
+ pa->num_formats = u.pa->num_formats;
+ pa->num_adaptors = rep.num_adaptors - ii;
+
+ /* GET ADAPTOR NAME */
+
+ size = u.pa->name_size;
+ u.buffer += (sz_xvAdaptorInfo + 3) & ~3;
+
+ if ( (name = (char *)Xmalloc(size+1)) == NULL)
+ {
+ SDL_NAME(XvFreeAdaptorInfo)(pas);
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+ SDL_strlcpy(name, u.string, size);
+ pa->name = name;
+
+ u.buffer += (size + 3) & ~3;
+
+ /* GET FORMATS */
+
+ size = pa->num_formats*sizeof(SDL_NAME(XvFormat));
+ if ((pfs=(SDL_NAME(XvFormat) *)Xmalloc(size))==NULL) {
+ SDL_NAME(XvFreeAdaptorInfo)(pas);
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+
+ pf = pfs;
+ for (jj=0; jj<pa->num_formats; jj++) {
+ pf->depth = u.pf->depth;
+ pf->visual_id = u.pf->visual;
+ pf++;
+
+ u.buffer += (sz_xvFormat + 3) & ~3;
+ }
+
+ pa->formats = pfs;
+
+ pa++;
+
+ }
+
+ *p_nAdaptors = rep.num_adaptors;
+ *p_pAdaptors = pas;
+
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (Success);
+}
+
+
+void
+SDL_NAME(XvFreeAdaptorInfo)(SDL_NAME(XvAdaptorInfo) *pAdaptors)
+{
+
+ SDL_NAME(XvAdaptorInfo) *pa;
+ int ii;
+
+ if (!pAdaptors) return;
+
+ pa = pAdaptors;
+
+ for (ii=0; ii<pAdaptors->num_adaptors; ii++, pa++)
+ {
+ if (pa->name)
+ {
+ Xfree(pa->name);
+ }
+ if (pa->formats)
+ {
+ Xfree(pa->formats);
+ }
+ }
+
+ Xfree(pAdaptors);
+}
+
+int
+SDL_NAME(XvQueryEncodings)(
+ Display *dpy,
+ XvPortID port,
+ unsigned int *p_nEncodings,
+ SDL_NAME(XvEncodingInfo) **p_pEncodings
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryEncodingsReq *req;
+ xvQueryEncodingsReply rep;
+ int size, jj;
+ char *name;
+ SDL_NAME(XvEncodingInfo) *pes, *pe;
+ char *buffer;
+ union
+ {
+ char *buffer;
+ char *string;
+ xvEncodingInfo *pe;
+ } u;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryEncodings, req);
+ req->port = port;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadReply);
+ }
+
+ size = rep.length << 2;
+ if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+ _XRead (dpy, buffer, size);
+
+ u.buffer = buffer;
+
+ /* GET ENCODINGS */
+
+ size = rep.num_encodings*sizeof(SDL_NAME(XvEncodingInfo));
+ if ( (pes = (SDL_NAME(XvEncodingInfo) *)Xmalloc(size)) == NULL) {
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+
+ /* INITIALIZE THE ENCODING POINTER */
+
+ pe = pes;
+ for (jj=0; jj<rep.num_encodings; jj++) {
+ pe->name = (char *)NULL;
+ pe->num_encodings = 0;
+ pe++;
+ }
+
+ pe = pes;
+ for (jj=0; jj<rep.num_encodings; jj++) {
+ pe->encoding_id = u.pe->encoding;
+ pe->width = u.pe->width;
+ pe->height = u.pe->height;
+ pe->rate.numerator = u.pe->rate.numerator;
+ pe->rate.denominator = u.pe->rate.denominator;
+ pe->num_encodings = rep.num_encodings - jj;
+
+ size = u.pe->name_size;
+ u.buffer += (sz_xvEncodingInfo + 3) & ~3;
+
+ if ( (name = (char *)Xmalloc(size+1)) == NULL) {
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadAlloc);
+ }
+ SDL_strlcpy(name, u.string, size);
+ pe->name = name;
+ pe++;
+
+ u.buffer += (size + 3) & ~3;
+ }
+
+ *p_nEncodings = rep.num_encodings;
+ *p_pEncodings = pes;
+
+ Xfree(buffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (Success);
+}
+
+void
+SDL_NAME(XvFreeEncodingInfo)(SDL_NAME(XvEncodingInfo) *pEncodings)
+{
+
+ SDL_NAME(XvEncodingInfo) *pe;
+ int ii;
+
+ if (!pEncodings) return;
+
+ pe = pEncodings;
+
+ for (ii=0; ii<pEncodings->num_encodings; ii++, pe++) {
+ if (pe->name) Xfree(pe->name);
+ }
+
+ Xfree(pEncodings);
+}
+
+int
+SDL_NAME(XvPutVideo)(
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ int vx, int vy,
+ unsigned int vw, unsigned int vh,
+ int dx, int dy,
+ unsigned int dw, unsigned int dh
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvPutVideoReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(PutVideo, req);
+
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->vid_x = vx;
+ req->vid_y = vy;
+ req->vid_w = vw;
+ req->vid_h = vh;
+ req->drw_x = dx;
+ req->drw_y = dy;
+ req->drw_w = dw;
+ req->drw_h = dh;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvPutStill)(
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ int vx, int vy,
+ unsigned int vw, unsigned int vh,
+ int dx, int dy,
+ unsigned int dw, unsigned int dh
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvPutStillReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(PutStill, req);
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->vid_x = vx;
+ req->vid_y = vy;
+ req->vid_w = vw;
+ req->vid_h = vh;
+ req->drw_x = dx;
+ req->drw_y = dy;
+ req->drw_w = dw;
+ req->drw_h = dh;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvGetVideo)(
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ int vx, int vy,
+ unsigned int vw, unsigned int vh,
+ int dx, int dy,
+ unsigned int dw, unsigned int dh
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvGetVideoReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(GetVideo, req);
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->vid_x = vx;
+ req->vid_y = vy;
+ req->vid_w = vw;
+ req->vid_h = vh;
+ req->drw_x = dx;
+ req->drw_y = dy;
+ req->drw_w = dw;
+ req->drw_h = dh;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvGetStill)(
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ int vx, int vy,
+ unsigned int vw, unsigned int vh,
+ int dx, int dy,
+ unsigned int dw, unsigned int dh
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvGetStillReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(GetStill, req);
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->vid_x = vx;
+ req->vid_y = vy;
+ req->vid_w = vw;
+ req->vid_h = vh;
+ req->drw_x = dx;
+ req->drw_y = dy;
+ req->drw_w = dw;
+ req->drw_h = dh;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvStopVideo)(
+ Display *dpy,
+ XvPortID port,
+ Drawable draw
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvStopVideoReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(StopVideo, req);
+ req->port = port;
+ req->drawable = draw;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvGrabPort)(
+ Display *dpy,
+ XvPortID port,
+ Time time
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ int result;
+ xvGrabPortReply rep;
+ xvGrabPortReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(GrabPort, req);
+ req->port = port;
+ req->time = time;
+
+ if (_XReply (dpy, (xReply *) &rep, 0, xTrue) == 0)
+ rep.result = GrabSuccess;
+
+ result = rep.result;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return result;
+}
+
+int
+SDL_NAME(XvUngrabPort)(
+ Display *dpy,
+ XvPortID port,
+ Time time
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvUngrabPortReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(UngrabPort, req);
+ req->port = port;
+ req->time = time;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvSelectVideoNotify)(
+ Display *dpy,
+ Drawable drawable,
+ Bool onoff
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvSelectVideoNotifyReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(SelectVideoNotify, req);
+ req->drawable = drawable;
+ req->onoff = onoff;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvSelectPortNotify)(
+ Display *dpy,
+ XvPortID port,
+ Bool onoff
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvSelectPortNotifyReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(SelectPortNotify, req);
+ req->port = port;
+ req->onoff = onoff;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int
+SDL_NAME(XvSetPortAttribute) (
+ Display *dpy,
+ XvPortID port,
+ Atom attribute,
+ int value
+)
+{
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvSetPortAttributeReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(SetPortAttribute, req);
+ req->port = port;
+ req->attribute = attribute;
+ req->value = value;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (Success);
+}
+
+int
+SDL_NAME(XvGetPortAttribute) (
+ Display *dpy,
+ XvPortID port,
+ Atom attribute,
+ int *p_value
+)
+{
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvGetPortAttributeReq *req;
+ xvGetPortAttributeReply rep;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(GetPortAttribute, req);
+ req->port = port;
+ req->attribute = attribute;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadReply);
+ }
+
+ *p_value = rep.value;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (Success);
+}
+
+int
+SDL_NAME(XvQueryBestSize)(
+ Display *dpy,
+ XvPortID port,
+ Bool motion,
+ unsigned int vid_w,
+ unsigned int vid_h,
+ unsigned int drw_w,
+ unsigned int drw_h,
+ unsigned int *p_actual_width,
+ unsigned int *p_actual_height
+)
+{
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryBestSizeReq *req;
+ xvQueryBestSizeReply rep;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryBestSize, req);
+ req->port = port;
+ req->motion = motion;
+ req->vid_w = vid_w;
+ req->vid_h = vid_h;
+ req->drw_w = drw_w;
+ req->drw_h = drw_h;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(XvBadReply);
+ }
+
+ *p_actual_width = rep.actual_width;
+ *p_actual_height = rep.actual_height;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return (Success);
+}
+
+
+SDL_NAME(XvAttribute)*
+SDL_NAME(XvQueryPortAttributes)(Display *dpy, XvPortID port, int *num)
+{
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryPortAttributesReq *req;
+ xvQueryPortAttributesReply rep;
+ SDL_NAME(XvAttribute) *ret = NULL;
+
+ *num = 0;
+
+ XvCheckExtension(dpy, info, NULL);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryPortAttributes, req);
+ req->port = port;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return ret;
+ }
+
+ if(rep.num_attributes) {
+ int size = (rep.num_attributes * sizeof(SDL_NAME(XvAttribute))) + rep.text_size;
+
+ if((ret = Xmalloc(size))) {
+ char* marker = (char*)(&ret[rep.num_attributes]);
+ xvAttributeInfo Info;
+ int i;
+
+ for(i = 0; i < rep.num_attributes; i++) {
+ _XRead(dpy, (char*)(&Info), sz_xvAttributeInfo);
+ ret[i].flags = (int)Info.flags;
+ ret[i].min_value = Info.min;
+ ret[i].max_value = Info.max;
+ ret[i].name = marker;
+ _XRead(dpy, marker, Info.size);
+ marker += Info.size;
+ (*num)++;
+ }
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return ret;
+}
+
+SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) (
+ Display *dpy,
+ XvPortID port,
+ int *num
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvListImageFormatsReq *req;
+ xvListImageFormatsReply rep;
+ SDL_NAME(XvImageFormatValues) *ret = NULL;
+
+ *num = 0;
+
+ XvCheckExtension(dpy, info, NULL);
+
+ LockDisplay(dpy);
+
+ XvGetReq(ListImageFormats, req);
+ req->port = port;
+
+ /* READ THE REPLY */
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ if(rep.num_formats) {
+ int size = (rep.num_formats * sizeof(SDL_NAME(XvImageFormatValues)));
+
+ if((ret = Xmalloc(size))) {
+ xvImageFormatInfo Info;
+ int i;
+
+ for(i = 0; i < rep.num_formats; i++) {
+ _XRead(dpy, (char*)(&Info), sz_xvImageFormatInfo);
+ ret[i].id = Info.id;
+ ret[i].type = Info.type;
+ ret[i].byte_order = Info.byte_order;
+ memcpy(&(ret[i].guid[0]), &(Info.guid[0]), 16);
+ ret[i].bits_per_pixel = Info.bpp;
+ ret[i].format = Info.format;
+ ret[i].num_planes = Info.num_planes;
+ ret[i].depth = Info.depth;
+ ret[i].red_mask = Info.red_mask;
+ ret[i].green_mask = Info.green_mask;
+ ret[i].blue_mask = Info.blue_mask;
+ ret[i].y_sample_bits = Info.y_sample_bits;
+ ret[i].u_sample_bits = Info.u_sample_bits;
+ ret[i].v_sample_bits = Info.v_sample_bits;
+ ret[i].horz_y_period = Info.horz_y_period;
+ ret[i].horz_u_period = Info.horz_u_period;
+ ret[i].horz_v_period = Info.horz_v_period;
+ ret[i].vert_y_period = Info.vert_y_period;
+ ret[i].vert_u_period = Info.vert_u_period;
+ ret[i].vert_v_period = Info.vert_v_period;
+ memcpy(&(ret[i].component_order[0]), &(Info.comp_order[0]), 32);
+ ret[i].scanline_order = Info.scanline_order;
+ (*num)++;
+ }
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return ret;
+}
+
+SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) (
+ Display *dpy,
+ XvPortID port,
+ int id,
+ char *data,
+ int width,
+ int height
+) {
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvQueryImageAttributesReq *req;
+ xvQueryImageAttributesReply rep;
+ SDL_NAME(XvImage) *ret = NULL;
+
+ XvCheckExtension(dpy, info, NULL);
+
+ LockDisplay(dpy);
+
+ XvGetReq(QueryImageAttributes, req);
+ req->id = id;
+ req->port = port;
+ req->width = width;
+ req->height = height;
+
+ /* READ THE REPLY */
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ if((ret = (SDL_NAME(XvImage)*)Xmalloc(sizeof(SDL_NAME(XvImage)) + (rep.num_planes << 3)))) {
+ ret->id = id;
+ ret->width = rep.width;
+ ret->height = rep.height;
+ ret->data_size = rep.data_size;
+ ret->num_planes = rep.num_planes;
+ ret->pitches = (int*)(&ret[1]);
+ ret->offsets = ret->pitches + rep.num_planes;
+ ret->data = data;
+ ret->obdata = NULL;
+ _XRead(dpy, (char*)(ret->pitches), rep.num_planes << 2);
+ _XRead(dpy, (char*)(ret->offsets), rep.num_planes << 2);
+ } else
+ _XEatData(dpy, rep.length << 2);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return ret;
+}
+
+SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) (
+ Display *dpy,
+ XvPortID port,
+ int id,
+ char *data,
+ int width,
+ int height,
+ XShmSegmentInfo *shminfo
+){
+ SDL_NAME(XvImage) *ret;
+
+ ret = SDL_NAME(XvCreateImage)(dpy, port, id, data, width, height);
+
+ if(ret) ret->obdata = (XPointer)shminfo;
+
+ return ret;
+}
+
+int SDL_NAME(XvPutImage) (
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ SDL_NAME(XvImage) *image,
+ int src_x,
+ int src_y,
+ unsigned int src_w,
+ unsigned int src_h,
+ int dest_x,
+ int dest_y,
+ unsigned int dest_w,
+ unsigned int dest_h
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ xvPutImageReq *req;
+ int len;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(PutImage, req);
+
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->id = image->id;
+ req->src_x = src_x;
+ req->src_y = src_y;
+ req->src_w = src_w;
+ req->src_h = src_h;
+ req->drw_x = dest_x;
+ req->drw_y = dest_y;
+ req->drw_w = dest_w;
+ req->drw_h = dest_h;
+ req->width = image->width;
+ req->height = image->height;
+
+ len = (image->data_size + 3) >> 2;
+ SetReqLen(req, len, len);
+
+ /* Yes it's kindof lame that we are sending the whole thing,
+ but for video all of it may be needed even if displaying
+ only a subsection, and I don't want to go through the
+ trouble of creating subregions to send */
+ Data(dpy, (char *)image->data, image->data_size);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int SDL_NAME(XvShmPutImage) (
+ Display *dpy,
+ XvPortID port,
+ Drawable d,
+ GC gc,
+ SDL_NAME(XvImage) *image,
+ int src_x,
+ int src_y,
+ unsigned int src_w,
+ unsigned int src_h,
+ int dest_x,
+ int dest_y,
+ unsigned int dest_w,
+ unsigned int dest_h,
+ Bool send_event
+){
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ XShmSegmentInfo *shminfo = (XShmSegmentInfo *)image->obdata;
+ xvShmPutImageReq *req;
+
+ XvCheckExtension(dpy, info, XvBadExtension);
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, gc);
+
+ XvGetReq(ShmPutImage, req);
+
+ req->port = port;
+ req->drawable = d;
+ req->gc = gc->gid;
+ req->shmseg = shminfo->shmseg;
+ req->id = image->id;
+ req->src_x = src_x;
+ req->src_y = src_y;
+ req->src_w = src_w;
+ req->src_h = src_h;
+ req->drw_x = dest_x;
+ req->drw_y = dest_y;
+ req->drw_w = dest_w;
+ req->drw_h = dest_h;
+ req->offset = image->data - shminfo->shmaddr;
+ req->width = image->width;
+ req->height = image->height;
+ req->send_event = send_event;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+
+static Bool
+xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
+{
+ XExtDisplayInfo *info = xv_find_display(dpy);
+ SDL_NAME(XvEvent) *re = (SDL_NAME(XvEvent) *)host;
+ xvEvent *event = (xvEvent *)wire;
+
+ XvCheckExtension(dpy, info, False);
+
+ switch((event->u.u.type & 0x7F) - info->codes->first_event)
+ {
+ case XvVideoNotify:
+ re->xvvideo.type = event->u.u.type & 0x7f;
+ re->xvvideo.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvvideo.display = dpy;
+ re->xvvideo.time = event->u.videoNotify.time;
+ re->xvvideo.reason = event->u.videoNotify.reason;
+ re->xvvideo.drawable = event->u.videoNotify.drawable;
+ re->xvvideo.port_id = event->u.videoNotify.port;
+ break;
+ case XvPortNotify:
+ re->xvport.type = event->u.u.type & 0x7f;
+ re->xvport.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvport.display = dpy;
+ re->xvport.time = event->u.portNotify.time;
+ re->xvport.port_id = event->u.portNotify.port;
+ re->xvport.attribute = event->u.portNotify.attribute;
+ re->xvport.value = event->u.portNotify.value;
+ break;
+ default:
+ return False;
+ }
+
+ return (True);
+}
+
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xv/Xvlibint.h b/distrib/sdl-1.2.15/src/video/Xext/Xv/Xvlibint.h
new file mode 100644
index 0000000..20df706
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xv/Xvlibint.h
@@ -0,0 +1,81 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/lib/Xv/Xvlibint.h,v 1.5 2001/07/25 15:04:53 dawes Exp $ */
+
+#ifndef XVLIBINT_H
+#define XVLIBINT_H
+/*
+** File:
+**
+** Xvlibint.h --- Xv library internal header file
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 01.24.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#define NEED_REPLIES
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include "../extensions/Xvproto.h"
+#include "../extensions/Xvlib.h"
+
+#if !defined(UNIXCPP)
+#define XvGetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = info->codes->major_opcode;\
+ req->xvReqType = xv_##name; \
+ req->length = (SIZEOF(xv##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(xv##name##Req);\
+ dpy->request++
+
+#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
+#define XvGetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xv/**/name/**/Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xv/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = info->codes->major_opcode;\
+ req->xvReqType = xv_/**/name;\
+ req->length = (SIZEOF(xv/**/name/**/Req))>>2;\
+ dpy->bufptr += SIZEOF(xv/**/name/**/Req);\
+ dpy->request++
+#endif
+
+
+#endif /* XVLIBINT_H */
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c
new file mode 100644
index 0000000..f2210e4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c
@@ -0,0 +1,721 @@
+/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.19 2001/08/18 02:41:30 dawes Exp $ */
+/*
+
+Copyright (c) 1995 Jon Tombs
+Copyright (c) 1995,1996 The XFree86 Project, Inc
+
+*/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#ifdef __EMX__ /* needed here to override certain constants in X headers */
+#define INCL_DOS
+#define INCL_DOSIOCTL
+#include <os2.h>
+#endif
+
+#if defined(linux)
+#define HAS_MMAP_ANON
+#include <sys/types.h>
+#include <sys/mman.h>
+/*#include <asm/page.h>*/ /* PAGE_SIZE */
+#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
+#define HAS_GETPAGESIZE
+#endif /* linux */
+
+#if defined(CSRG_BASED)
+#define HAS_MMAP_ANON
+#define HAS_GETPAGESIZE
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif /* CSRG_BASED */
+
+#if defined(DGUX)
+#define HAS_GETPAGESIZE
+#define MMAP_DEV_ZERO
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#endif /* DGUX */
+
+#if defined(SVR4) && !defined(DGUX)
+#define MMAP_DEV_ZERO
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#endif /* SVR4 && !DGUX */
+
+#if defined(sun) && !defined(SVR4) /* SunOS */
+#define MMAP_DEV_ZERO /* doesn't SunOS have MAP_ANON ?? */
+#define HAS_GETPAGESIZE
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif /* sun && !SVR4 */
+
+#ifdef XNO_SYSCONF
+#undef _SC_PAGESIZE
+#endif
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include "../extensions/xf86dga.h"
+#include "../extensions/xf86dgastr.h"
+#include "../extensions/Xext.h"
+#include "../extensions/extutil.h"
+
+extern XExtDisplayInfo* SDL_NAME(xdga_find_display)(Display*);
+extern char *SDL_NAME(xdga_extension_name);
+
+#define XF86DGACheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
+
+/*****************************************************************************
+ * *
+ * public XFree86-DGA Extension routines *
+ * *
+ *****************************************************************************/
+
+Bool SDL_NAME(XF86DGAQueryExtension) (
+ Display *dpy,
+ int *event_basep,
+ int *error_basep
+){
+ return SDL_NAME(XDGAQueryExtension)(dpy, event_basep, error_basep);
+}
+
+Bool SDL_NAME(XF86DGAQueryVersion)(
+ Display* dpy,
+ int* majorVersion,
+ int* minorVersion
+){
+ return SDL_NAME(XDGAQueryVersion)(dpy, majorVersion, minorVersion);
+}
+
+Bool SDL_NAME(XF86DGAGetVideoLL)(
+ Display* dpy,
+ int screen,
+ int *offset,
+ int *width,
+ int *bank_size,
+ int *ram_size
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAGetVideoLLReply rep;
+ xXF86DGAGetVideoLLReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAGetVideoLL, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAGetVideoLL;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *offset = /*(char *)*/rep.offset;
+ *width = rep.width;
+ *bank_size = rep.bank_size;
+ *ram_size = rep.ram_size;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+
+Bool SDL_NAME(XF86DGADirectVideoLL)(
+ Display* dpy,
+ int screen,
+ int enable
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGADirectVideoReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGADirectVideo, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGADirectVideo;
+ req->screen = screen;
+ req->enable = enable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XSync(dpy,False);
+ return True;
+}
+
+Bool SDL_NAME(XF86DGAGetViewPortSize)(
+ Display* dpy,
+ int screen,
+ int *width,
+ int *height
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAGetViewPortSizeReply rep;
+ xXF86DGAGetViewPortSizeReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAGetViewPortSize, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAGetViewPortSize;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+
+Bool SDL_NAME(XF86DGASetViewPort)(
+ Display* dpy,
+ int screen,
+ int x,
+ int y
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGASetViewPortReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGASetViewPort, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGASetViewPort;
+ req->screen = screen;
+ req->x = x;
+ req->y = y;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XSync(dpy,False);
+ return True;
+}
+
+
+Bool SDL_NAME(XF86DGAGetVidPage)(
+ Display* dpy,
+ int screen,
+ int *vpage
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAGetVidPageReply rep;
+ xXF86DGAGetVidPageReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAGetVidPage, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAGetVidPage;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *vpage = rep.vpage;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+
+Bool SDL_NAME(XF86DGASetVidPage)(
+ Display* dpy,
+ int screen,
+ int vpage
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGASetVidPageReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGASetVidPage, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGASetVidPage;
+ req->screen = screen;
+ req->vpage = vpage;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XSync(dpy,False);
+ return True;
+}
+
+Bool SDL_NAME(XF86DGAInstallColormap)(
+ Display* dpy,
+ int screen,
+ Colormap cmap
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAInstallColormapReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAInstallColormap, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAInstallColormap;
+ req->screen = screen;
+ req->id = cmap;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XSync(dpy,False);
+ return True;
+}
+
+Bool SDL_NAME(XF86DGAQueryDirectVideo)(
+ Display *dpy,
+ int screen,
+ int *flags
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAQueryDirectVideoReply rep;
+ xXF86DGAQueryDirectVideoReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAQueryDirectVideo, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAQueryDirectVideo;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *flags = rep.flags;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool SDL_NAME(XF86DGAViewPortChanged)(
+ Display *dpy,
+ int screen,
+ int n
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXF86DGAViewPortChangedReply rep;
+ xXF86DGAViewPortChangedReq *req;
+
+ XF86DGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86DGAViewPortChanged, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XF86DGAViewPortChanged;
+ req->screen = screen;
+ req->n = n;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return rep.result;
+}
+
+
+
+/* Helper functions */
+
+#include <X11/Xmd.h>
+#include "../extensions/xf86dga.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#if defined(ISC)
+# define HAS_SVR3_MMAP
+# include <sys/types.h>
+# include <errno.h>
+
+# include <sys/at_ansi.h>
+# include <sys/kd.h>
+
+# include <sys/sysmacros.h>
+# include <sys/immu.h>
+# include <sys/region.h>
+
+# include <sys/mmap.h>
+#else
+# if !defined(Lynx)
+# if !defined(__EMX__)
+# include <sys/mman.h>
+# endif
+# else
+# include <sys/types.h>
+# include <errno.h>
+# include <smem.h>
+# endif
+#endif
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+
+#if defined(SVR4) && !defined(sun) && !defined(SCO325)
+#define DEV_MEM "/dev/pmem"
+#elif defined(SVR4) && defined(sun)
+#define DEV_MEM "/dev/xsvc"
+#else
+#define DEV_MEM "/dev/mem"
+#endif
+
+typedef struct {
+ unsigned long physaddr; /* actual requested physical address */
+ unsigned long size; /* actual requested map size */
+ unsigned long delta; /* delta to account for page alignment */
+ void * vaddr; /* mapped address, without the delta */
+ int refcount; /* reference count */
+} MapRec, *MapPtr;
+
+typedef struct {
+ Display * display;
+ int screen;
+ MapPtr map;
+} ScrRec, *ScrPtr;
+
+static int mapFd = -1;
+static int numMaps = 0;
+static int numScrs = 0;
+static MapPtr *mapList = NULL;
+static ScrPtr *scrList = NULL;
+
+static MapPtr
+AddMap(void)
+{
+ MapPtr *old;
+
+ old = mapList;
+ mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1));
+ if (!mapList) {
+ mapList = old;
+ return NULL;
+ }
+ mapList[numMaps] = malloc(sizeof(MapRec));
+ if (!mapList[numMaps])
+ return NULL;
+ return mapList[numMaps++];
+}
+
+static ScrPtr
+AddScr(void)
+{
+ ScrPtr *old;
+
+ old = scrList;
+ scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1));
+ if (!scrList) {
+ scrList = old;
+ return NULL;
+ }
+ scrList[numScrs] = malloc(sizeof(ScrRec));
+ if (!scrList[numScrs])
+ return NULL;
+ return scrList[numScrs++];
+}
+
+static MapPtr
+FindMap(unsigned long address, unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < numMaps; i++) {
+ if (mapList[i]->physaddr == address &&
+ mapList[i]->size == size)
+ return mapList[i];
+ }
+ return NULL;
+}
+
+static ScrPtr
+FindScr(Display *display, int screen)
+{
+ int i;
+
+ for (i = 0; i < numScrs; i++) {
+ if (scrList[i]->display == display &&
+ scrList[i]->screen == screen)
+ return scrList[i];
+ }
+ return NULL;
+}
+
+static void *
+MapPhysAddress(unsigned long address, unsigned long size)
+{
+ unsigned long offset, delta;
+ int pagesize = -1;
+ void *vaddr;
+ MapPtr mp;
+#if defined(ISC) && defined(HAS_SVR3_MMAP)
+ struct kd_memloc mloc;
+#elif defined(__EMX__)
+ APIRET rc;
+ ULONG action;
+ HFILE hfd;
+#endif
+
+ if ((mp = FindMap(address, size))) {
+ mp->refcount++;
+ return (void *)((unsigned long)mp->vaddr + mp->delta);
+ }
+
+#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#ifdef _SC_PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#endif
+#ifdef HAS_GETPAGESIZE
+ if (pagesize == -1)
+ pagesize = getpagesize();
+#endif
+#ifdef PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = PAGE_SIZE;
+#endif
+ if (pagesize == -1)
+ pagesize = 4096;
+
+ delta = address % pagesize;
+ offset = address - delta;
+
+#if defined(ISC) && defined(HAS_SVR3_MMAP)
+ if (mapFd < 0) {
+ if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
+ return NULL;
+ }
+ mloc.vaddr = (char *)0;
+ mloc.physaddr = (char *)offset;
+ mloc.length = size + delta;
+ mloc.ioflg=1;
+
+ if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
+ return NULL;
+#elif defined (__EMX__)
+ /*
+ * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
+ * Consecutive calling of this routine will make PMAP$ driver run out
+ * of memory handles. Some umap/close mechanism should be provided
+ */
+
+ rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
+ OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
+ if (rc != 0)
+ return NULL;
+ {
+ struct map_ioctl {
+ union {
+ ULONG phys;
+ void* user;
+ } a;
+ ULONG size;
+ } pmap,dmap;
+ ULONG plen,dlen;
+#define XFREE86_PMAP 0x76
+#define PMAP_MAP 0x44
+
+ pmap.a.phys = offset;
+ pmap.size = size + delta;
+ rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
+ (PULONG)&pmap, sizeof(pmap), &plen,
+ (PULONG)&dmap, sizeof(dmap), &dlen);
+ if (rc == 0) {
+ vaddr = dmap.a.user;
+ }
+ }
+ if (rc != 0)
+ return NULL;
+#elif defined (Lynx)
+ vaddr = (void *)smem_create("XF86DGA", (char *)offset,
+ size + delta, SM_READ|SM_WRITE);
+#else
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+ if (mapFd < 0) {
+ if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
+ return NULL;
+ }
+ vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
+ if (vaddr == (void *)-1)
+ return NULL;
+#endif
+
+ if (!vaddr) {
+ if (!(mp = AddMap()))
+ return NULL;
+ mp->physaddr = address;
+ mp->size = size;
+ mp->delta = delta;
+ mp->vaddr = vaddr;
+ mp->refcount = 1;
+ }
+ return (void *)((unsigned long)vaddr + delta);
+}
+
+/*
+ * Still need to find a clean way of detecting the death of a DGA app
+ * and returning things to normal - Jon
+ * This is here to help debugging without rebooting... Also C-A-BS
+ * should restore text mode.
+ */
+
+int
+SDL_NAME(XF86DGAForkApp)(int screen)
+{
+ pid_t pid;
+ int status;
+ int i;
+
+ /* fork the app, parent hangs around to clean up */
+ if ((pid = fork()) > 0) {
+ ScrPtr sp;
+
+ waitpid(pid, &status, 0);
+ for (i = 0; i < numScrs; i++) {
+ sp = scrList[i];
+ SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0);
+ XSync(sp->display, False);
+ }
+ if (WIFEXITED(status))
+ exit(0);
+ else
+ exit(-1);
+ }
+ return pid;
+}
+
+
+Bool
+SDL_NAME(XF86DGADirectVideo)(
+ Display *dis,
+ int screen,
+ int enable
+){
+ ScrPtr sp;
+ MapPtr mp = NULL;
+
+ if ((sp = FindScr(dis, screen)))
+ mp = sp->map;
+
+ if (enable & XF86DGADirectGraphics) {
+#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
+ && !defined(__EMX__)
+ if (mp && mp->vaddr)
+ mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);
+#endif
+ } else {
+#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
+ && !defined(__EMX__)
+ if (mp && mp->vaddr)
+ mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);
+#elif defined(Lynx)
+ /* XXX this doesn't allow enable after disable */
+ smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH);
+ smem_remove("XF86DGA");
+#endif
+ }
+
+ SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable);
+ return 1;
+}
+
+
+static void
+XF86cleanup(int sig)
+{
+ ScrPtr sp;
+ int i;
+ static char beenhere = 0;
+
+ if (beenhere)
+ exit(3);
+ beenhere = 1;
+
+ for (i = 0; i < numScrs; i++) {
+ sp = scrList[i];
+ SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0);
+ XSync(sp->display, False);
+ }
+ exit(3);
+}
+
+Bool
+SDL_NAME(XF86DGAGetVideo)(
+ Display *dis,
+ int screen,
+ char **addr,
+ int *width,
+ int *bank,
+ int *ram
+){
+ /*unsigned long*/ int offset;
+ static int beenHere = 0;
+ ScrPtr sp;
+ MapPtr mp;
+
+ if (!(sp = FindScr(dis, screen))) {
+ if (!(sp = AddScr())) {
+ fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
+ exit(-2);
+ }
+ sp->display = dis;
+ sp->screen = screen;
+ sp->map = NULL;
+ }
+
+ SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram);
+
+ *addr = MapPhysAddress(offset, *bank);
+ if (*addr == NULL) {
+ fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
+ strerror(errno));
+ exit(-2);
+ }
+
+ if ((mp = FindMap(offset, *bank)))
+ sp->map = mp;
+
+ if (!beenHere) {
+ beenHere = 1;
+ atexit((void(*)(void))XF86cleanup);
+ /* one shot XF86cleanup attempts */
+ signal(SIGSEGV, XF86cleanup);
+#ifdef SIGBUS
+ signal(SIGBUS, XF86cleanup);
+#endif
+ signal(SIGHUP, XF86cleanup);
+ signal(SIGFPE, XF86cleanup);
+ }
+
+ return 1;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA2.c b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA2.c
new file mode 100644
index 0000000..11d4fdd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA2.c
@@ -0,0 +1,993 @@
+/* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 dawes Exp $ */
+/*
+
+Copyright (c) 1995 Jon Tombs
+Copyright (c) 1995,1996 The XFree86 Project, Inc
+
+*/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#ifdef __EMX__ /* needed here to override certain constants in X headers */
+#define INCL_DOS
+#define INCL_DOSIOCTL
+#include <os2.h>
+#endif
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include "../extensions/xf86dga.h"
+#include "../extensions/xf86dgastr.h"
+#include "../extensions/Xext.h"
+#include "../extensions/extutil.h"
+#include <stdio.h>
+
+#if defined(ENABLE_FBCON) /* Needed for framebuffer console support */
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#endif
+
+/* If you change this, change the Bases[] array below as well */
+#define MAX_HEADS 16
+
+char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
+
+static XExtensionInfo _xdga_info_data;
+static XExtensionInfo *xdga_info = &_xdga_info_data;
+
+
+Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32);
+void SDL_NAME(XDGAUnmapFramebuffer)(int);
+unsigned char* SDL_NAME(XDGAGetMappedMemory)(int);
+
+#define XDGACheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static int xdga_close_display(Display *dpy, XExtCodes *codes);
+static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
+static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
+
+static XExtensionHooks xdga_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xdga_close_display, /* close_display */
+ xdga_wire_to_event, /* wire_to_event */
+ xdga_event_to_wire, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
+
+
+XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info,
+ "XFree86-DGA",
+ &xdga_extension_hooks,
+ 0, NULL)
+
+
+static Status
+xdga_event_to_wire(
+ Display *dpy,
+ XEvent *event,
+ xEvent *wire_ev
+){
+ return True;
+}
+
+static Bool
+xdga_wire_to_event(
+ Display *dpy,
+ XEvent *event,
+ xEvent *wire_ev
+){
+ dgaEvent *wire = (dgaEvent *) wire_ev;
+ SDL_NAME(XDGAButtonEvent) *bevent;
+ SDL_NAME(XDGAKeyEvent) *kevent;
+ SDL_NAME(XDGAMotionEvent) *mevent;
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+
+ XDGACheckExtension (dpy, info, False);
+
+ switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
+ case MotionNotify:
+ mevent = (SDL_NAME(XDGAMotionEvent)*)event;
+ mevent->type = wire->u.u.type & 0x7F;
+ mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
+ mevent->display = dpy;
+ mevent->screen = wire->u.event.screen;
+ mevent->time = wire->u.event.time;
+ mevent->state = wire->u.event.state;
+ mevent->dx = wire->u.event.dx;
+ mevent->dy = wire->u.event.dy;
+ return True;
+ case ButtonPress:
+ case ButtonRelease:
+ bevent = (SDL_NAME(XDGAButtonEvent)*)event;
+ bevent->type = wire->u.u.type & 0x7F;
+ bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
+ bevent->display = dpy;
+ bevent->screen = wire->u.event.screen;
+ bevent->time = wire->u.event.time;
+ bevent->state = wire->u.event.state;
+ bevent->button = wire->u.u.detail;
+ return True;
+ case KeyPress:
+ case KeyRelease:
+ kevent = (SDL_NAME(XDGAKeyEvent)*)event;
+ kevent->type = wire->u.u.type & 0x7F;
+ kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
+ kevent->display = dpy;
+ kevent->screen = wire->u.event.screen;
+ kevent->time = wire->u.event.time;
+ kevent->state = wire->u.event.state;
+ kevent->keycode = wire->u.u.detail;
+ return True;
+ }
+
+ return False;
+}
+
+
+Bool SDL_NAME(XDGAQueryExtension) (
+ Display *dpy,
+ int *event_basep,
+ int *error_basep
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+
+Bool SDL_NAME(XDGAQueryVersion)(
+ Display *dpy,
+ int *majorVersion,
+ int *minorVersion
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAQueryVersionReply rep;
+ xXDGAQueryVersionReq *req;
+
+ XDGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XDGAQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAQueryVersion;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *majorVersion = rep.majorVersion;
+ *minorVersion = rep.minorVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (*majorVersion >= 2)
+ {
+ int i, j;
+
+ for (i = 0, j = info->codes->first_event;
+ i < XF86DGANumberEvents;
+ i++, j++)
+ {
+ XESetWireToEvent(dpy, j, xdga_wire_to_event);
+ XESetEventToWire(dpy, j, xdga_event_to_wire);
+ }
+ SDL_NAME(XDGASetClientVersion)(dpy);
+ }
+ return True;
+}
+
+Bool SDL_NAME(XDGASetClientVersion)(
+ Display *dpy
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGASetClientVersionReq *req;
+
+ XDGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XDGASetClientVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGASetClientVersion;
+ req->major = XDGA_MAJOR_VERSION;
+ req->minor = XDGA_MINOR_VERSION;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool SDL_NAME(XDGAOpenFramebuffer)(
+ Display *dpy,
+ int screen
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAOpenFramebufferReply rep;
+ xXDGAOpenFramebufferReq *req;
+ char *deviceName = NULL;
+ Bool ret;
+
+ XDGACheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XDGAOpenFramebuffer, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAOpenFramebuffer;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ if(rep.length) {
+ deviceName = Xmalloc(rep.length << 2);
+ _XRead(dpy, deviceName, rep.length << 2);
+ }
+
+ ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName,
+ (unsigned char*)(long)rep.mem1,
+ rep.size, rep.offset, rep.extra);
+
+ if(deviceName)
+ Xfree(deviceName);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return ret;
+}
+
+void SDL_NAME(XDGACloseFramebuffer)(
+ Display *dpy,
+ int screen
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGACloseFramebufferReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ SDL_NAME(XDGAUnmapFramebuffer)(screen);
+
+ LockDisplay(dpy);
+ GetReq(XDGACloseFramebuffer, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGACloseFramebuffer;
+ req->screen = screen;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+
+
+SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
+ Display *dpy,
+ int screen,
+ int *num
+){
+ XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAQueryModesReply rep;
+ xXDGAQueryModesReq *req;
+ SDL_NAME(XDGAMode) *modes = NULL;
+
+ *num = 0;
+
+ XDGACheckExtension (dpy, dinfo, NULL);
+
+ LockDisplay(dpy);
+ GetReq(XDGAQueryModes, req);
+ req->reqType = dinfo->codes->major_opcode;
+ req->dgaReqType = X_XDGAQueryModes;
+ req->screen = screen;
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ if(rep.length) {
+ xXDGAModeInfo info;
+ int i, size;
+ char *offset;
+
+ size = rep.length << 2;
+ size -= rep.number * sz_xXDGAModeInfo; /* find text size */
+ modes = (SDL_NAME(XDGAMode)*)Xmalloc((rep.number * sizeof(SDL_NAME(XDGAMode))) + size);
+ offset = (char*)(&modes[rep.number]); /* start of text */
+
+
+ if(modes) {
+ for(i = 0; i < rep.number; i++) {
+ _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
+
+ modes[i].num = info.num;
+ modes[i].verticalRefresh =
+ (float)info.vsync_num / (float)info.vsync_den;
+ modes[i].flags = info.flags;
+ modes[i].imageWidth = info.image_width;
+ modes[i].imageHeight = info.image_height;
+ modes[i].pixmapWidth = info.pixmap_width;
+ modes[i].pixmapHeight = info.pixmap_height;
+ modes[i].bytesPerScanline = info.bytes_per_scanline;
+ modes[i].byteOrder = info.byte_order;
+ modes[i].depth = info.depth;
+ modes[i].bitsPerPixel = info.bpp;
+ modes[i].redMask = info.red_mask;
+ modes[i].greenMask = info.green_mask;
+ modes[i].blueMask = info.blue_mask;
+ modes[i].visualClass = info.visual_class;
+ modes[i].viewportWidth = info.viewport_width;
+ modes[i].viewportHeight = info.viewport_height;
+ modes[i].xViewportStep = info.viewport_xstep;
+ modes[i].yViewportStep = info.viewport_ystep;
+ modes[i].maxViewportX = info.viewport_xmax;
+ modes[i].maxViewportY = info.viewport_ymax;
+ modes[i].viewportFlags = info.viewport_flags;
+ modes[i].reserved1 = info.reserved1;
+ modes[i].reserved2 = info.reserved2;
+
+ _XRead(dpy, offset, info.name_size);
+ modes[i].name = offset;
+ offset += info.name_size;
+ }
+ *num = rep.number;
+ } else
+ _XEatData(dpy, rep.length << 2);
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return modes;
+}
+
+
+SDL_NAME(XDGADevice) *
+SDL_NAME(XDGASetMode)(
+ Display *dpy,
+ int screen,
+ int mode
+){
+ XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
+ xXDGASetModeReply rep;
+ xXDGASetModeReq *req;
+ SDL_NAME(XDGADevice) *dev = NULL;
+ Pixmap pid;
+
+ XDGACheckExtension (dpy, dinfo, NULL);
+
+ LockDisplay(dpy);
+ GetReq(XDGASetMode, req);
+ req->reqType = dinfo->codes->major_opcode;
+ req->dgaReqType = X_XDGASetMode;
+ req->screen = screen;
+ req->mode = mode;
+ req->pid = pid = XAllocID(dpy);
+
+ if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ if(rep.length) {
+ xXDGAModeInfo info;
+ int size;
+
+ size = rep.length << 2;
+ size -= sz_xXDGAModeInfo; /* get text size */
+
+ dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size);
+
+ if(dev) {
+ _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
+
+ dev->mode.num = info.num;
+ dev->mode.verticalRefresh =
+ (float)info.vsync_num / (float)info.vsync_den;
+ dev->mode.flags = info.flags;
+ dev->mode.imageWidth = info.image_width;
+ dev->mode.imageHeight = info.image_height;
+ dev->mode.pixmapWidth = info.pixmap_width;
+ dev->mode.pixmapHeight = info.pixmap_height;
+ dev->mode.bytesPerScanline = info.bytes_per_scanline;
+ dev->mode.byteOrder = info.byte_order;
+ dev->mode.depth = info.depth;
+ dev->mode.bitsPerPixel = info.bpp;
+ dev->mode.redMask = info.red_mask;
+ dev->mode.greenMask = info.green_mask;
+ dev->mode.blueMask = info.blue_mask;
+ dev->mode.visualClass = info.visual_class;
+ dev->mode.viewportWidth = info.viewport_width;
+ dev->mode.viewportHeight = info.viewport_height;
+ dev->mode.xViewportStep = info.viewport_xstep;
+ dev->mode.yViewportStep = info.viewport_ystep;
+ dev->mode.maxViewportX = info.viewport_xmax;
+ dev->mode.maxViewportY = info.viewport_ymax;
+ dev->mode.viewportFlags = info.viewport_flags;
+ dev->mode.reserved1 = info.reserved1;
+ dev->mode.reserved2 = info.reserved2;
+
+ dev->mode.name = (char*)(&dev[1]);
+ _XRead(dpy, dev->mode.name, info.name_size);
+
+ dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
+ dev->data = SDL_NAME(XDGAGetMappedMemory)(screen);
+
+ if(dev->data)
+ dev->data += rep.offset;
+ }
+ /* not sure what to do if the allocation fails */
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return dev;
+}
+
+
+void SDL_NAME(XDGASetViewport)(
+ Display *dpy,
+ int screen,
+ int x,
+ int y,
+ int flags
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGASetViewportReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGASetViewport, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGASetViewport;
+ req->screen = screen;
+ req->x = x;
+ req->y = y;
+ req->flags = flags;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+
+void SDL_NAME(XDGAInstallColormap)(
+ Display *dpy,
+ int screen,
+ Colormap cmap
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAInstallColormapReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGAInstallColormap, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAInstallColormap;
+ req->screen = screen;
+ req->cmap = cmap;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void SDL_NAME(XDGASelectInput)(
+ Display *dpy,
+ int screen,
+ long mask
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGASelectInputReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGASelectInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGASelectInput;
+ req->screen = screen;
+ req->mask = mask;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void SDL_NAME(XDGAFillRectangle)(
+ Display *dpy,
+ int screen,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned long color
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAFillRectangleReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGAFillRectangle, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAFillRectangle;
+ req->screen = screen;
+ req->x = x;
+ req->y = y;
+ req->width = width;
+ req->height = height;
+ req->color = color;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void SDL_NAME(XDGACopyArea)(
+ Display *dpy,
+ int screen,
+ int srcx,
+ int srcy,
+ unsigned int width,
+ unsigned int height,
+ int dstx,
+ int dsty
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGACopyAreaReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGACopyArea, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGACopyArea;
+ req->screen = screen;
+ req->srcx = srcx;
+ req->srcy = srcy;
+ req->width = width;
+ req->height = height;
+ req->dstx = dstx;
+ req->dsty = dsty;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void SDL_NAME(XDGACopyTransparentArea)(
+ Display *dpy,
+ int screen,
+ int srcx,
+ int srcy,
+ unsigned int width,
+ unsigned int height,
+ int dstx,
+ int dsty,
+ unsigned long key
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGACopyTransparentAreaReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGACopyTransparentArea, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGACopyTransparentArea;
+ req->screen = screen;
+ req->srcx = srcx;
+ req->srcy = srcy;
+ req->width = width;
+ req->height = height;
+ req->dstx = dstx;
+ req->dsty = dsty;
+ req->key = key;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+
+int SDL_NAME(XDGAGetViewportStatus)(
+ Display *dpy,
+ int screen
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAGetViewportStatusReply rep;
+ xXDGAGetViewportStatusReq *req;
+ int status = 0;
+
+ XDGACheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq(XDGAGetViewportStatus, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAGetViewportStatus;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
+ status = rep.status;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return status;
+}
+
+void SDL_NAME(XDGASync)(
+ Display *dpy,
+ int screen
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGASyncReply rep;
+ xXDGASyncReq *req;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGASync, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGASync;
+ req->screen = screen;
+ _XReply(dpy, (xReply *)&rep, 0, xFalse);
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+
+void SDL_NAME(XDGAChangePixmapMode)(
+ Display *dpy,
+ int screen,
+ int *x,
+ int *y,
+ int mode
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGAChangePixmapModeReq *req;
+ xXDGAChangePixmapModeReply rep;
+
+ XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
+
+ LockDisplay(dpy);
+ GetReq(XDGAChangePixmapMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGAChangePixmapMode;
+ req->screen = screen;
+ req->x = *x;
+ req->y = *y;
+ req->flags = mode;
+ _XReply(dpy, (xReply *)&rep, 0, xFalse);
+ *x = rep.x;
+ *y = rep.y;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+Colormap SDL_NAME(XDGACreateColormap)(
+ Display *dpy,
+ int screen,
+ SDL_NAME(XDGADevice) *dev,
+ int alloc
+){
+ XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
+ xXDGACreateColormapReq *req;
+ Colormap cid;
+
+ XDGACheckExtension (dpy, info, -1);
+
+ LockDisplay(dpy);
+ GetReq(XDGACreateColormap, req);
+ req->reqType = info->codes->major_opcode;
+ req->dgaReqType = X_XDGACreateColormap;
+ req->screen = screen;
+ req->mode = dev->mode.num;
+ req->alloc = alloc;
+ cid = req->id = XAllocID(dpy);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return cid;
+}
+
+
+void SDL_NAME(XDGAKeyEventToXKeyEvent)(
+ SDL_NAME(XDGAKeyEvent)* dk,
+ XKeyEvent* xk
+){
+ xk->type = dk->type;
+ xk->serial = dk->serial;
+ xk->send_event = False;
+ xk->display = dk->display;
+ xk->window = RootWindow(dk->display, dk->screen);
+ xk->root = xk->window;
+ xk->subwindow = None;
+ xk->time = dk->time;
+ xk->x = xk->y = xk->x_root = xk->y_root = 0;
+ xk->state = dk->state;
+ xk->keycode = dk->keycode;
+ xk->same_screen = True;
+}
+
+#include <X11/Xmd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#if defined(ISC)
+# define HAS_SVR3_MMAP
+# include <sys/types.h>
+# include <errno.h>
+
+# include <sys/at_ansi.h>
+# include <sys/kd.h>
+
+# include <sys/sysmacros.h>
+# include <sys/immu.h>
+# include <sys/region.h>
+
+# include <sys/mmap.h>
+#else
+# if !defined(Lynx)
+# if !defined(__EMX__)
+# include <sys/mman.h>
+# endif
+# else
+# include <sys/types.h>
+# include <errno.h>
+# include <smem.h>
+# endif
+#endif
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+
+#if defined(SVR4) && !defined(sun) && !defined(SCO325)
+#define DEV_MEM "/dev/pmem"
+#elif defined(SVR4) && defined(sun)
+#define DEV_MEM "/dev/xsvc"
+#else
+#define DEV_MEM "/dev/mem"
+#endif
+
+
+
+typedef struct _DGAMapRec{
+ unsigned char *physical;
+ unsigned char *virtual;
+ CARD32 size;
+ int fd;
+ int screen;
+ struct _DGAMapRec *next;
+} DGAMapRec, *DGAMapPtr;
+
+static Bool
+DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
+static void DGAUnmapPhysical(DGAMapPtr);
+
+static DGAMapPtr _Maps = NULL;
+
+
+unsigned char*
+SDL_NAME(XDGAGetMappedMemory)(int screen)
+{
+ DGAMapPtr pMap = _Maps;
+ unsigned char *pntr = NULL;
+
+ while(pMap != NULL) {
+ if(pMap->screen == screen) {
+ pntr = pMap->virtual;
+ break;
+ }
+ pMap = pMap->next;
+ }
+
+ return pntr;
+}
+
+Bool
+SDL_NAME(XDGAMapFramebuffer)(
+ int screen,
+ char *name, /* optional device name */
+ unsigned char* base, /* physical memory */
+ CARD32 size, /* size */
+ CARD32 offset, /* optional offset */
+ CARD32 extra /* optional extra data */
+){
+ DGAMapPtr pMap = _Maps;
+ Bool result;
+
+ /* is it already mapped ? */
+ while(pMap != NULL) {
+ if(pMap->screen == screen)
+ return True;
+ pMap = pMap->next;
+ }
+
+ if(extra & XDGANeedRoot) {
+ /* we should probably check if we have root permissions and
+ return False here */
+
+ }
+
+ pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
+
+ result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
+
+ if(result) {
+ pMap->next = _Maps;
+ _Maps = pMap;
+ } else
+ Xfree(pMap);
+
+ return result;
+}
+
+void
+SDL_NAME(XDGAUnmapFramebuffer)(int screen)
+{
+ DGAMapPtr pMap = _Maps;
+ DGAMapPtr pPrev = NULL;
+
+ /* is it already mapped */
+ while(pMap != NULL) {
+ if(pMap->screen == screen)
+ break;
+ pPrev = pMap;
+ pMap = pMap->next;
+ }
+
+ if(!pMap)
+ return;
+
+ DGAUnmapPhysical(pMap);
+
+ if(!pPrev)
+ _Maps = pMap->next;
+ else
+ pPrev->next = pMap->next;
+
+ Xfree(pMap);
+}
+
+
+static Bool
+DGAMapPhysical(
+ int screen,
+ char *name, /* optional device name */
+ unsigned char* base, /* physical memory */
+ CARD32 size, /* size */
+ CARD32 offset, /* optional offset */
+ CARD32 extra, /* optional extra data */
+ DGAMapPtr pMap
+) {
+#if defined(ISC) && defined(HAS_SVR3_MMAP)
+ struct kd_memloc mloc;
+#elif defined(__EMX__)
+ APIRET rc;
+ ULONG action;
+ HFILE hfd;
+#endif
+
+ base += offset;
+
+ pMap->screen = screen;
+ pMap->physical = base;
+ pMap->size = size;
+
+#if defined(ISC) && defined(HAS_SVR3_MMAP)
+ if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
+ return False;
+ mloc.vaddr = (char *)0;
+ mloc.physaddr = (char *)base;
+ mloc.length = size;
+ mloc.ioflg=1;
+
+ if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
+ return False;
+#elif defined (__EMX__)
+ /*
+ * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
+ * Consecutive calling of this routine will make PMAP$ driver run out
+ * of memory handles. Some umap/close mechanism should be provided
+ */
+
+ rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
+ OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
+ if (rc != 0)
+ return False;
+ {
+ struct map_ioctl {
+ union {
+ ULONG phys;
+ void* user;
+ } a;
+ ULONG size;
+ } pmap,dmap;
+ ULONG plen,dlen;
+#define XFREE86_PMAP 0x76
+#define PMAP_MAP 0x44
+
+ pmap.a.phys = base;
+ pmap.size = size;
+ rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
+ (PULONG)&pmap, sizeof(pmap), &plen,
+ (PULONG)&dmap, sizeof(dmap), &dlen);
+ if (rc == 0) {
+ pMap->virtual = dmap.a.user;
+ }
+ }
+ if (rc != 0)
+ return False;
+#elif defined (Lynx)
+ pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
+#else
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+ if (!name)
+ name = DEV_MEM;
+ if ((pMap->fd = open(name, O_RDWR)) < 0)
+#if defined(ENABLE_FBCON)
+ { /* /dev/fb0 fallback added by Sam Lantinga <hercules@lokigames.com> */
+ /* Try to fall back to /dev/fb on Linux - FIXME: verify the device */
+ struct fb_fix_screeninfo finfo;
+
+ if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) {
+ return False;
+ }
+ /* The useable framebuffer console memory may not be the whole
+ framebuffer that X has access to. :-(
+ */
+ if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
+ close(pMap->fd);
+ return False;
+ }
+ /* Warning: On PPC, the size and virtual need to be offset by:
+ (((long)finfo.smem_start) -
+ (((long)finfo.smem_start)&~(PAGE_SIZE-1)))
+ */
+ base = 0;
+ size = pMap->size = finfo.smem_len;
+ }
+#else
+ return False;
+#endif
+ pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, pMap->fd, (off_t)((size_t)base));
+ if (pMap->virtual == (void *)-1)
+ return False;
+#endif
+
+#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
+ && !defined(__EMX__)
+ mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
+#endif
+
+ return True;
+}
+
+
+
+static void
+DGAUnmapPhysical(DGAMapPtr pMap)
+{
+#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
+ && !defined(__EMX__)
+ mprotect(pMap->virtual,pMap->size, PROT_READ);
+#elif defined(Lynx)
+ /* XXX this doesn't allow enable after disable */
+ smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
+ smem_remove("XF86DGA");
+#endif
+
+
+ /* We need to unmap and close too !!!!!!!!!!*/
+}
diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xxf86vm/XF86VMode.c b/distrib/sdl-1.2.15/src/video/Xext/Xxf86vm/XF86VMode.c
new file mode 100644
index 0000000..5cb2190
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/Xxf86vm/XF86VMode.c
@@ -0,0 +1,1226 @@
+/* $XConsortium: XF86VMode.c /main/2 1995/11/14 18:17:58 kaleb $ */
+/* $XFree86: xc/lib/Xxf86vm/XF86VMode.c,v 3.32 2001/07/25 15:04:54 dawes Exp $ */
+/*
+
+Copyright (c) 1995 Kaleb S. KEITHLEY
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
+OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY.
+
+*/
+/* $XConsortium: XF86VMode.c /main/4 1996/01/16 07:52:25 kaleb CHECKEDOUT $ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+#ifndef XBUILD_IN_CLIENT
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+#include "../extensions/xf86vmstr.h"
+#include "../extensions/Xext.h"
+#include "../extensions/extutil.h"
+#else
+#include "include/extensions/xf86vmstr.h"
+#include "include/extensions/Xext.h"
+#include "include/extensions/extutil.h"
+#endif
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifndef MODE_BAD
+#define MODE_BAD 255
+#endif
+
+static XExtensionInfo _xf86vidmode_info_data;
+static XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data;
+static char *xf86vidmode_extension_name = XF86VIDMODENAME;
+
+#define XF86VidModeCheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, xf86vidmode_extension_name, val)
+
+/*****************************************************************************
+ * *
+ * private utility routines *
+ * *
+ *****************************************************************************/
+
+static XEXT_CLOSE_DISPLAY_PROTO(close_display);
+static /* const */ XExtensionHooks xf86vidmode_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ close_display, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info,
+ xf86vidmode_extension_name,
+ &xf86vidmode_extension_hooks,
+ 0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info)
+
+
+/*****************************************************************************
+ * *
+ * public XFree86-VidMode Extension routines *
+ * *
+ *****************************************************************************/
+
+Bool
+SDL_NAME(XF86VidModeQueryExtension) (dpy, event_basep, error_basep)
+ Display *dpy;
+ int *event_basep, *error_basep;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+Bool
+SDL_NAME(XF86VidModeQueryVersion)(dpy, majorVersion, minorVersion)
+ Display* dpy;
+ int* majorVersion;
+ int* minorVersion;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeQueryVersionReply rep;
+ xXF86VidModeQueryVersionReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeQueryVersion;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *majorVersion = rep.majorVersion;
+ *minorVersion = rep.minorVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ if (*majorVersion >= 2)
+ SDL_NAME(XF86VidModeSetClientVersion)(dpy);
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeSetClientVersion)(Display *dpy)
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86VidModeSetClientVersionReq *req;
+
+ XF86VidModeCheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeSetClientVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSetClientVersion;
+ req->major = XF86VIDMODE_MAJOR_VERSION;
+ req->minor = XF86VIDMODE_MINOR_VERSION;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeSetGamma)(Display *dpy, int screen, SDL_NAME(XF86VidModeGamma) *Gamma)
+{
+ XExtDisplayInfo *info = find_display(dpy);
+ xXF86VidModeSetGammaReq *req;
+
+ XF86VidModeCheckExtension(dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeSetGamma, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSetGamma;
+ req->screen = screen;
+ req->red = (CARD32)(Gamma->red * 10000.);
+ req->green = (CARD32)(Gamma->green * 10000.);
+ req->blue = (CARD32)(Gamma->blue * 10000.);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetGamma)(Display *dpy, int screen, SDL_NAME(XF86VidModeGamma) *Gamma)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetGammaReply rep;
+ xXF86VidModeGetGammaReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetGamma, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetGamma;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ Gamma->red = ((float)rep.red) / 10000.;
+ Gamma->green = ((float)rep.green) / 10000.;
+ Gamma->blue = ((float)rep.blue) / 10000.;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetModeLine)(dpy, screen, dotclock, modeline)
+ Display* dpy;
+ int screen;
+ int* dotclock;
+ SDL_NAME(XF86VidModeModeLine)* modeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetModeLineReply rep;
+ xXF86OldVidModeGetModeLineReply oldrep;
+ xXF86VidModeGetModeLineReq *req;
+ int majorVersion, minorVersion;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetModeLine, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetModeLine;
+ req->screen = screen;
+
+ if (majorVersion < 2) {
+ if (!_XReply(dpy, (xReply *)&oldrep,
+ (SIZEOF(xXF86OldVidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *dotclock = oldrep.dotclock;
+ modeline->hdisplay = oldrep.hdisplay;
+ modeline->hsyncstart = oldrep.hsyncstart;
+ modeline->hsyncend = oldrep.hsyncend;
+ modeline->htotal = oldrep.htotal;
+ modeline->hskew = 0;
+ modeline->vdisplay = oldrep.vdisplay;
+ modeline->vsyncstart = oldrep.vsyncstart;
+ modeline->vsyncend = oldrep.vsyncend;
+ modeline->vtotal = oldrep.vtotal;
+ modeline->flags = oldrep.flags;
+ modeline->privsize = oldrep.privsize;
+ } else {
+ if (!_XReply(dpy, (xReply *)&rep,
+ (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *dotclock = rep.dotclock;
+ modeline->hdisplay = rep.hdisplay;
+ modeline->hsyncstart = rep.hsyncstart;
+ modeline->hsyncend = rep.hsyncend;
+ modeline->htotal = rep.htotal;
+ modeline->hskew = rep.hskew;
+ modeline->vdisplay = rep.vdisplay;
+ modeline->vsyncstart = rep.vsyncstart;
+ modeline->vsyncend = rep.vsyncend;
+ modeline->vtotal = rep.vtotal;
+ modeline->flags = rep.flags;
+ modeline->privsize = rep.privsize;
+ }
+
+ if (modeline->privsize > 0) {
+ if (!(modeline->private = Xcalloc(modeline->privsize, sizeof(INT32)))) {
+ _XEatData(dpy, (modeline->privsize) * sizeof(INT32));
+ Xfree(modeline->private);
+ return False;
+ }
+ _XRead(dpy, (char*)modeline->private, modeline->privsize * sizeof(INT32));
+ } else {
+ modeline->private = NULL;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetAllModeLines)(dpy, screen, modecount, modelinesPtr)
+ Display* dpy;
+ int screen;
+ int* modecount;
+ SDL_NAME(XF86VidModeModeInfo) ***modelinesPtr;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetAllModeLinesReply rep;
+ xXF86VidModeGetAllModeLinesReq *req;
+ SDL_NAME(XF86VidModeModeInfo) *mdinfptr, **modelines;
+ xXF86VidModeModeInfo xmdline;
+ xXF86OldVidModeModeInfo oldxmdline;
+ int i;
+ int majorVersion, minorVersion;
+ Bool protocolBug = False;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ /*
+ * Note: There was a bug in the protocol implementation in versions
+ * 0.x with x < 8 (the .private field wasn't being passed over the wire).
+ * Check the server's version, and accept the old format if appropriate.
+ */
+
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+ if (majorVersion == 0 && minorVersion < 8) {
+ protocolBug = True;
+#ifdef DEBUG
+ fprintf(stderr, "XF86VidModeGetAllModeLines: Warning: Xserver is"
+ "running an old version (%d.%d)\n", majorVersion,
+ minorVersion);
+#endif
+ }
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetAllModeLines, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetAllModeLines;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep,
+ (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *modecount = rep.modecount;
+
+ if (!(modelines = (SDL_NAME(XF86VidModeModeInfo) **) Xcalloc(rep.modecount,
+ sizeof(SDL_NAME(XF86VidModeModeInfo) *)
+ +sizeof(SDL_NAME(XF86VidModeModeInfo))))) {
+ if (majorVersion < 2)
+ _XEatData(dpy, (rep.modecount) * sizeof(xXF86OldVidModeModeInfo));
+ else
+ _XEatData(dpy, (rep.modecount) * sizeof(xXF86VidModeModeInfo));
+ Xfree(modelines);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ mdinfptr = (SDL_NAME(XF86VidModeModeInfo) *) (
+ (char *) modelines
+ + rep.modecount*sizeof(SDL_NAME(XF86VidModeModeInfo) *)
+ );
+
+ for (i = 0; i < rep.modecount; i++) {
+ modelines[i] = mdinfptr++;
+ if (majorVersion < 2) {
+ _XRead(dpy, (char*)&oldxmdline, sizeof(xXF86OldVidModeModeInfo));
+ modelines[i]->dotclock = oldxmdline.dotclock;
+ modelines[i]->hdisplay = oldxmdline.hdisplay;
+ modelines[i]->hsyncstart = oldxmdline.hsyncstart;
+ modelines[i]->hsyncend = oldxmdline.hsyncend;
+ modelines[i]->htotal = oldxmdline.htotal;
+ modelines[i]->hskew = 0;
+ modelines[i]->vdisplay = oldxmdline.vdisplay;
+ modelines[i]->vsyncstart = oldxmdline.vsyncstart;
+ modelines[i]->vsyncend = oldxmdline.vsyncend;
+ modelines[i]->vtotal = oldxmdline.vtotal;
+ modelines[i]->flags = oldxmdline.flags;
+ if (protocolBug) {
+ modelines[i]->privsize = 0;
+ modelines[i]->private = NULL;
+ } else {
+ modelines[i]->privsize = oldxmdline.privsize;
+ if (oldxmdline.privsize > 0) {
+ if (!(modelines[i]->private =
+ Xcalloc(oldxmdline.privsize, sizeof(INT32)))) {
+ _XEatData(dpy, (oldxmdline.privsize) * sizeof(INT32));
+ Xfree(modelines[i]->private);
+ } else {
+ _XRead(dpy, (char*)modelines[i]->private,
+ oldxmdline.privsize * sizeof(INT32));
+ }
+ } else {
+ modelines[i]->private = NULL;
+ }
+ }
+ } else {
+ _XRead(dpy, (char*)&xmdline, sizeof(xXF86VidModeModeInfo));
+ modelines[i]->dotclock = xmdline.dotclock;
+ modelines[i]->hdisplay = xmdline.hdisplay;
+ modelines[i]->hsyncstart = xmdline.hsyncstart;
+ modelines[i]->hsyncend = xmdline.hsyncend;
+ modelines[i]->htotal = xmdline.htotal;
+ modelines[i]->hskew = xmdline.hskew;
+ modelines[i]->vdisplay = xmdline.vdisplay;
+ modelines[i]->vsyncstart = xmdline.vsyncstart;
+ modelines[i]->vsyncend = xmdline.vsyncend;
+ modelines[i]->vtotal = xmdline.vtotal;
+ modelines[i]->flags = xmdline.flags;
+ if (protocolBug) {
+ modelines[i]->privsize = 0;
+ modelines[i]->private = NULL;
+ } else {
+ modelines[i]->privsize = xmdline.privsize;
+ if (xmdline.privsize > 0) {
+ if (!(modelines[i]->private =
+ Xcalloc(xmdline.privsize, sizeof(INT32)))) {
+ _XEatData(dpy, (xmdline.privsize) * sizeof(INT32));
+ Xfree(modelines[i]->private);
+ } else {
+ _XRead(dpy, (char*)modelines[i]->private,
+ xmdline.privsize * sizeof(INT32));
+ }
+ } else {
+ modelines[i]->private = NULL;
+ }
+ }
+ }
+ }
+ *modelinesPtr = modelines;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+/*
+ * GetReq replacement for use with VidMode protocols earlier than 2.0
+ */
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define GetOldReq(name, oldname, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x##oldname##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x##oldname##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_##name;\
+ req->length = (SIZEOF(x##oldname##Req))>>2;\
+ dpy->bufptr += SIZEOF(x##oldname##Req);\
+ dpy->request++
+
+#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
+#define GetOldReq(name, oldname, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x/**/oldname/**/Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x/**/oldname/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = X_/**/name;\
+ req->length = (SIZEOF(x/**/oldname/**/Req))>>2;\
+ dpy->bufptr += SIZEOF(x/**/oldname/**/Req);\
+ dpy->request++
+#endif
+
+Bool
+SDL_NAME(XF86VidModeAddModeLine) (dpy, screen, newmodeline, aftermodeline)
+ Display *dpy;
+ int screen;
+ SDL_NAME(XF86VidModeModeInfo)* newmodeline;
+ SDL_NAME(XF86VidModeModeInfo)* aftermodeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeAddModeLineReq *req;
+ xXF86OldVidModeAddModeLineReq *oldreq;
+ int majorVersion, minorVersion;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+
+ LockDisplay(dpy);
+ if (majorVersion < 2) {
+ GetOldReq(XF86VidModeAddModeLine, XF86OldVidModeAddModeLine, oldreq);
+ oldreq->reqType = info->codes->major_opcode;
+ oldreq->xf86vidmodeReqType = X_XF86VidModeAddModeLine;
+ oldreq->screen = screen;
+ oldreq->dotclock = newmodeline->dotclock;
+ oldreq->hdisplay = newmodeline->hdisplay;
+ oldreq->hsyncstart = newmodeline->hsyncstart;
+ oldreq->hsyncend = newmodeline->hsyncend;
+ oldreq->htotal = newmodeline->htotal;
+ oldreq->vdisplay = newmodeline->vdisplay;
+ oldreq->vsyncstart = newmodeline->vsyncstart;
+ oldreq->vsyncend = newmodeline->vsyncend;
+ oldreq->vtotal = newmodeline->vtotal;
+ oldreq->flags = newmodeline->flags;
+ oldreq->privsize = newmodeline->privsize;
+ if (aftermodeline != NULL) {
+ oldreq->after_dotclock = aftermodeline->dotclock;
+ oldreq->after_hdisplay = aftermodeline->hdisplay;
+ oldreq->after_hsyncstart = aftermodeline->hsyncstart;
+ oldreq->after_hsyncend = aftermodeline->hsyncend;
+ oldreq->after_htotal = aftermodeline->htotal;
+ oldreq->after_vdisplay = aftermodeline->vdisplay;
+ oldreq->after_vsyncstart = aftermodeline->vsyncstart;
+ oldreq->after_vsyncend = aftermodeline->vsyncend;
+ oldreq->after_vtotal = aftermodeline->vtotal;
+ oldreq->after_flags = aftermodeline->flags;
+ } else {
+ oldreq->after_dotclock = 0;
+ oldreq->after_hdisplay = 0;
+ oldreq->after_hsyncstart = 0;
+ oldreq->after_hsyncend = 0;
+ oldreq->after_htotal = 0;
+ oldreq->after_vdisplay = 0;
+ oldreq->after_vsyncstart = 0;
+ oldreq->after_vsyncend = 0;
+ oldreq->after_vtotal = 0;
+ oldreq->after_flags = 0;
+ }
+ if (newmodeline->privsize) {
+ oldreq->length += newmodeline->privsize;
+ Data32(dpy, (long *) newmodeline->private,
+ newmodeline->privsize * sizeof(INT32));
+ }
+ } else {
+ GetReq(XF86VidModeAddModeLine, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeAddModeLine;
+ req->screen = screen;
+ req->dotclock = newmodeline->dotclock;
+ req->hdisplay = newmodeline->hdisplay;
+ req->hsyncstart = newmodeline->hsyncstart;
+ req->hsyncend = newmodeline->hsyncend;
+ req->htotal = newmodeline->htotal;
+ req->hskew = newmodeline->hskew;
+ req->vdisplay = newmodeline->vdisplay;
+ req->vsyncstart = newmodeline->vsyncstart;
+ req->vsyncend = newmodeline->vsyncend;
+ req->vtotal = newmodeline->vtotal;
+ req->flags = newmodeline->flags;
+ req->privsize = newmodeline->privsize;
+ if (aftermodeline != NULL) {
+ req->after_dotclock = aftermodeline->dotclock;
+ req->after_hdisplay = aftermodeline->hdisplay;
+ req->after_hsyncstart = aftermodeline->hsyncstart;
+ req->after_hsyncend = aftermodeline->hsyncend;
+ req->after_htotal = aftermodeline->htotal;
+ req->after_hskew = aftermodeline->hskew;
+ req->after_vdisplay = aftermodeline->vdisplay;
+ req->after_vsyncstart = aftermodeline->vsyncstart;
+ req->after_vsyncend = aftermodeline->vsyncend;
+ req->after_vtotal = aftermodeline->vtotal;
+ req->after_flags = aftermodeline->flags;
+ } else {
+ req->after_dotclock = 0;
+ req->after_hdisplay = 0;
+ req->after_hsyncstart = 0;
+ req->after_hsyncend = 0;
+ req->after_htotal = 0;
+ req->after_hskew = 0;
+ req->after_vdisplay = 0;
+ req->after_vsyncstart = 0;
+ req->after_vsyncend = 0;
+ req->after_vtotal = 0;
+ req->after_flags = 0;
+ }
+ if (newmodeline->privsize) {
+ req->length += newmodeline->privsize;
+ Data32(dpy, (long *) newmodeline->private,
+ newmodeline->privsize * sizeof(INT32));
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeDeleteModeLine) (dpy, screen, modeline)
+ Display *dpy;
+ int screen;
+ SDL_NAME(XF86VidModeModeInfo)* modeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeDeleteModeLineReq *req;
+ xXF86OldVidModeDeleteModeLineReq *oldreq;
+ int majorVersion, minorVersion;
+
+ XF86VidModeCheckExtension (dpy, info, 0);
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+
+ LockDisplay(dpy);
+ if (majorVersion < 2) {
+ GetOldReq(XF86VidModeDeleteModeLine, XF86OldVidModeDeleteModeLine, oldreq);
+ oldreq->reqType = info->codes->major_opcode;
+ oldreq->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine;
+ oldreq->screen = screen;
+ oldreq->dotclock = modeline->dotclock;
+ oldreq->hdisplay = modeline->hdisplay;
+ oldreq->hsyncstart = modeline->hsyncstart;
+ oldreq->hsyncend = modeline->hsyncend;
+ oldreq->htotal = modeline->htotal;
+ oldreq->vdisplay = modeline->vdisplay;
+ oldreq->vsyncstart = modeline->vsyncstart;
+ oldreq->vsyncend = modeline->vsyncend;
+ oldreq->vtotal = modeline->vtotal;
+ oldreq->flags = modeline->flags;
+ oldreq->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ oldreq->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ } else {
+ GetReq(XF86VidModeDeleteModeLine, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine;
+ req->screen = screen;
+ req->dotclock = modeline->dotclock;
+ req->hdisplay = modeline->hdisplay;
+ req->hsyncstart = modeline->hsyncstart;
+ req->hsyncend = modeline->hsyncend;
+ req->htotal = modeline->htotal;
+ req->hskew = modeline->hskew;
+ req->vdisplay = modeline->vdisplay;
+ req->vsyncstart = modeline->vsyncstart;
+ req->vsyncend = modeline->vsyncend;
+ req->vtotal = modeline->vtotal;
+ req->flags = modeline->flags;
+ req->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ req->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeModModeLine) (dpy, screen, modeline)
+ Display *dpy;
+ int screen;
+ SDL_NAME(XF86VidModeModeLine)* modeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeModModeLineReq *req;
+ xXF86OldVidModeModModeLineReq *oldreq;
+ int majorVersion, minorVersion;
+
+ XF86VidModeCheckExtension (dpy, info, 0);
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+
+ LockDisplay(dpy);
+ if (majorVersion < 2) {
+ GetOldReq(XF86VidModeModModeLine, XF86OldVidModeModModeLine, oldreq);
+ oldreq->reqType = info->codes->major_opcode;
+ oldreq->xf86vidmodeReqType = X_XF86VidModeModModeLine;
+ oldreq->screen = screen;
+ oldreq->hdisplay = modeline->hdisplay;
+ oldreq->hsyncstart = modeline->hsyncstart;
+ oldreq->hsyncend = modeline->hsyncend;
+ oldreq->htotal = modeline->htotal;
+ oldreq->vdisplay = modeline->vdisplay;
+ oldreq->vsyncstart = modeline->vsyncstart;
+ oldreq->vsyncend = modeline->vsyncend;
+ oldreq->vtotal = modeline->vtotal;
+ oldreq->flags = modeline->flags;
+ oldreq->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ oldreq->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ } else {
+ GetReq(XF86VidModeModModeLine, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeModModeLine;
+ req->screen = screen;
+ req->hdisplay = modeline->hdisplay;
+ req->hsyncstart = modeline->hsyncstart;
+ req->hsyncend = modeline->hsyncend;
+ req->htotal = modeline->htotal;
+ req->hskew = modeline->hskew;
+ req->vdisplay = modeline->vdisplay;
+ req->vsyncstart = modeline->vsyncstart;
+ req->vsyncend = modeline->vsyncend;
+ req->vtotal = modeline->vtotal;
+ req->flags = modeline->flags;
+ req->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ req->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Status
+SDL_NAME(XF86VidModeValidateModeLine) (dpy, screen, modeline)
+ Display *dpy;
+ int screen;
+ SDL_NAME(XF86VidModeModeInfo)* modeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeValidateModeLineReq *req;
+ xXF86OldVidModeValidateModeLineReq *oldreq;
+ xXF86VidModeValidateModeLineReply rep;
+ int majorVersion, minorVersion;
+
+ XF86VidModeCheckExtension (dpy, info, 0);
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+
+ LockDisplay(dpy);
+
+ if (majorVersion < 2) {
+ GetOldReq(XF86VidModeValidateModeLine, XF86OldVidModeValidateModeLine, oldreq);
+ oldreq->reqType = info->codes->major_opcode;
+ oldreq->xf86vidmodeReqType = X_XF86VidModeValidateModeLine;
+ oldreq->screen = screen;
+ oldreq->dotclock = modeline->dotclock;
+ oldreq->hdisplay = modeline->hdisplay;
+ oldreq->hsyncstart = modeline->hsyncstart;
+ oldreq->hsyncend = modeline->hsyncend;
+ oldreq->htotal = modeline->htotal;
+ oldreq->vdisplay = modeline->vdisplay;
+ oldreq->vsyncstart = modeline->vsyncstart;
+ oldreq->vsyncend = modeline->vsyncend;
+ oldreq->vtotal = modeline->vtotal;
+ oldreq->flags = modeline->flags;
+ oldreq->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ oldreq->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ } else {
+ GetReq(XF86VidModeValidateModeLine, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeValidateModeLine;
+ req->screen = screen;
+ req->dotclock = modeline->dotclock;
+ req->hdisplay = modeline->hdisplay;
+ req->hsyncstart = modeline->hsyncstart;
+ req->hsyncend = modeline->hsyncend;
+ req->htotal = modeline->htotal;
+ req->hskew = modeline->hskew;
+ req->vdisplay = modeline->vdisplay;
+ req->vsyncstart = modeline->vsyncstart;
+ req->vsyncend = modeline->vsyncend;
+ req->vtotal = modeline->vtotal;
+ req->flags = modeline->flags;
+ req->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ req->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ }
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return MODE_BAD;
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return rep.status;
+}
+
+Bool
+SDL_NAME(XF86VidModeSwitchMode)(dpy, screen, zoom)
+ Display* dpy;
+ int screen;
+ int zoom;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeSwitchModeReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeSwitchMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSwitchMode;
+ req->screen = screen;
+ req->zoom = zoom;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeSwitchToMode)(dpy, screen, modeline)
+ Display* dpy;
+ int screen;
+ SDL_NAME(XF86VidModeModeInfo)* modeline;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeSwitchToModeReq *req;
+ xXF86OldVidModeSwitchToModeReq *oldreq;
+ int majorVersion, minorVersion;
+ Bool protocolBug = False;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ /*
+ * Note: There was a bug in the protocol implementation in versions
+ * 0.x with x < 8 (the .private field wasn't expected to be sent over
+ * the wire). Check the server's version, and accept the old format
+ * if appropriate.
+ */
+
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+ if (majorVersion == 0 && minorVersion < 8) {
+ protocolBug = True;
+#ifdef DEBUG
+ fprintf(stderr, "XF86VidModeSwitchToMode: Warning: Xserver is"
+ "running an old version (%d.%d)\n", majorVersion,
+ minorVersion);
+#endif
+ }
+
+ LockDisplay(dpy);
+ if (majorVersion < 2) {
+ GetOldReq(XF86VidModeSwitchToMode, XF86OldVidModeSwitchToMode, oldreq);
+ oldreq->reqType = info->codes->major_opcode;
+ oldreq->xf86vidmodeReqType = X_XF86VidModeSwitchToMode;
+ oldreq->screen = screen;
+ oldreq->dotclock = modeline->dotclock;
+ oldreq->hdisplay = modeline->hdisplay;
+ oldreq->hsyncstart = modeline->hsyncstart;
+ oldreq->hsyncend = modeline->hsyncend;
+ oldreq->htotal = modeline->htotal;
+ oldreq->vdisplay = modeline->vdisplay;
+ oldreq->vsyncstart = modeline->vsyncstart;
+ oldreq->vsyncend = modeline->vsyncend;
+ oldreq->vtotal = modeline->vtotal;
+ oldreq->flags = modeline->flags;
+ if (protocolBug) {
+ oldreq->privsize = 0;
+ } else {
+ oldreq->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ oldreq->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ }
+ } else {
+ GetReq(XF86VidModeSwitchToMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSwitchToMode;
+ req->screen = screen;
+ req->dotclock = modeline->dotclock;
+ req->hdisplay = modeline->hdisplay;
+ req->hsyncstart = modeline->hsyncstart;
+ req->hsyncend = modeline->hsyncend;
+ req->htotal = modeline->htotal;
+ req->hskew = modeline->hskew;
+ req->vdisplay = modeline->vdisplay;
+ req->vsyncstart = modeline->vsyncstart;
+ req->vsyncend = modeline->vsyncend;
+ req->vtotal = modeline->vtotal;
+ req->flags = modeline->flags;
+ if (protocolBug) {
+ req->privsize = 0;
+ } else {
+ req->privsize = modeline->privsize;
+ if (modeline->privsize) {
+ req->length += modeline->privsize;
+ Data32(dpy, (long *) modeline->private,
+ modeline->privsize * sizeof(INT32));
+ }
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeLockModeSwitch)(dpy, screen, lock)
+ Display* dpy;
+ int screen;
+ int lock;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeLockModeSwitchReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeLockModeSwitch, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeLockModeSwitch;
+ req->screen = screen;
+ req->lock = lock;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetMonitor)(dpy, screen, monitor)
+ Display* dpy;
+ int screen;
+ SDL_NAME(XF86VidModeMonitor)* monitor;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetMonitorReply rep;
+ xXF86VidModeGetMonitorReq *req;
+ CARD32 syncrange;
+ int i;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetMonitor, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetMonitor;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ monitor->nhsync = rep.nhsync;
+ monitor->nvsync = rep.nvsync;
+#if 0
+ monitor->bandwidth = (float)rep.bandwidth / 1e6;
+#endif
+ if (rep.vendorLength) {
+ if (!(monitor->vendor = (char *)Xcalloc(rep.vendorLength + 1, 1))) {
+ _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
+ ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ } else {
+ monitor->vendor = NULL;
+ }
+ if (rep.modelLength) {
+ if (!(monitor->model = Xcalloc(rep.modelLength + 1, 1))) {
+ _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
+ ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
+ if (monitor->vendor)
+ Xfree(monitor->vendor);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ } else {
+ monitor->model = NULL;
+ }
+ if (!(monitor->hsync = Xcalloc(rep.nhsync, sizeof(SDL_NAME(XF86VidModeSyncRange))))) {
+ _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
+ ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
+
+ if (monitor->vendor)
+ Xfree(monitor->vendor);
+ if (monitor->model)
+ Xfree(monitor->model);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ if (!(monitor->vsync = Xcalloc(rep.nvsync, sizeof(SDL_NAME(XF86VidModeSyncRange))))) {
+ _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
+ ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
+ if (monitor->vendor)
+ Xfree(monitor->vendor);
+ if (monitor->model)
+ Xfree(monitor->model);
+ Xfree(monitor->hsync);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ for (i = 0; i < rep.nhsync; i++) {
+ _XRead(dpy, (char *)&syncrange, 4);
+ monitor->hsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0;
+ monitor->hsync[i].hi = (float)(syncrange >> 16) / 100.0;
+ }
+ for (i = 0; i < rep.nvsync; i++) {
+ _XRead(dpy, (char *)&syncrange, 4);
+ monitor->vsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0;
+ monitor->vsync[i].hi = (float)(syncrange >> 16) / 100.0;
+ }
+ if (rep.vendorLength)
+ _XReadPad(dpy, monitor->vendor, rep.vendorLength);
+ else
+ monitor->vendor = "";
+ if (rep.modelLength)
+ _XReadPad(dpy, monitor->model, rep.modelLength);
+ else
+ monitor->model = "";
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetViewPort)(dpy, screen, x, y)
+ Display* dpy;
+ int screen;
+ int *x, *y;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetViewPortReply rep;
+ xXF86VidModeGetViewPortReq *req;
+ int majorVersion, minorVersion;
+ Bool protocolBug = False;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ /*
+ * Note: There was a bug in the protocol implementation in versions
+ * 0.x with x < 8 (no reply was sent, so the client would hang)
+ * Check the server's version, and don't wait for a reply with older
+ * versions.
+ */
+
+ SDL_NAME(XF86VidModeQueryVersion)(dpy, &majorVersion, &minorVersion);
+ if (majorVersion == 0 && minorVersion < 8) {
+ protocolBug = True;
+#ifdef DEBUG
+ fprintf(stderr, "XF86VidModeGetViewPort: Warning: Xserver is"
+ "running an old version (%d.%d)\n", majorVersion,
+ minorVersion);
+#endif
+ }
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetViewPort, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetViewPort;
+ req->screen = screen;
+ if (protocolBug) {
+ *x = 0;
+ *y = 0;
+ } else {
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *x = rep.x;
+ *y = rep.y;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeSetViewPort)(dpy, screen, x, y)
+ Display* dpy;
+ int screen;
+ int x, y;
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeSetViewPortReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeSetViewPort, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSetViewPort;
+ req->screen = screen;
+ req->x = x;
+ req->y = y;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeGetDotClocks)(dpy, screen,
+ flagsPtr, numclocksPtr, maxclocksPtr, clocksPtr)
+ Display* dpy;
+ int screen;
+ int *flagsPtr, *numclocksPtr, *maxclocksPtr, *clocksPtr[];
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetDotClocksReply rep;
+ xXF86VidModeGetDotClocksReq *req;
+ int i, *dotclocks;
+ CARD32 dotclk;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetDotClocks, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetDotClocks;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply *)&rep,
+ (SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2, xFalse))
+ {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *numclocksPtr = rep.clocks;
+ *maxclocksPtr = rep.maxclocks;
+ *flagsPtr = rep.flags;
+
+ if (!(dotclocks = (int*) Xcalloc(rep.clocks, sizeof(int)))) {
+ _XEatData(dpy, (rep.clocks) * 4);
+ Xfree(dotclocks);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ for (i = 0; i < rep.clocks; i++) {
+ _XRead(dpy, (char*)&dotclk, 4);
+ dotclocks[i] = dotclk;
+ }
+ *clocksPtr = dotclocks;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool
+SDL_NAME(XF86VidModeSetGammaRamp) (
+ Display *dpy,
+ int screen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+)
+{
+ int length = (size + 1) & ~1;
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeSetGammaRampReq *req;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+ LockDisplay(dpy);
+ GetReq(XF86VidModeSetGammaRamp, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeSetGammaRamp;
+ req->screen = screen;
+ req->length += (length >> 1) * 3;
+ req->size = size;
+ _XSend(dpy, (char*)red, size * 2);
+ _XSend(dpy, (char*)green, size * 2);
+ _XSend(dpy, (char*)blue, size * 2);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+
+Bool
+SDL_NAME(XF86VidModeGetGammaRamp) (
+ Display *dpy,
+ int screen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetGammaRampReq *req;
+ xXF86VidModeGetGammaRampReply rep;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetGammaRamp, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetGammaRamp;
+ req->screen = screen;
+ req->size = size;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ if(rep.size) {
+ _XRead(dpy, (char*)red, rep.size << 1);
+ _XRead(dpy, (char*)green, rep.size << 1);
+ _XRead(dpy, (char*)blue, rep.size << 1);
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
+Bool SDL_NAME(XF86VidModeGetGammaRampSize)(
+ Display *dpy,
+ int screen,
+ int *size
+)
+{
+ XExtDisplayInfo *info = find_display (dpy);
+ xXF86VidModeGetGammaRampSizeReq *req;
+ xXF86VidModeGetGammaRampSizeReply rep;
+
+ *size = 0;
+
+ XF86VidModeCheckExtension (dpy, info, False);
+
+ LockDisplay(dpy);
+ GetReq(XF86VidModeGetGammaRampSize, req);
+ req->reqType = info->codes->major_opcode;
+ req->xf86vidmodeReqType = X_XF86VidModeGetGammaRampSize;
+ req->screen = screen;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ *size = rep.size;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return True;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/Xext.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xext.h
new file mode 100644
index 0000000..9edf319
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xext.h
@@ -0,0 +1,50 @@
+/*
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+/* $XFree86: xc/include/extensions/Xext.h,v 1.7 2005/01/27 03:03:09 dawes Exp $ */
+
+#ifndef _XEXT_H_
+#define _XEXT_H_
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+typedef int (*XExtensionErrorHandler)(Display *, _Xconst char *,
+ _Xconst char *);
+
+extern XExtensionErrorHandler XSetExtensionErrorHandler(
+ XExtensionErrorHandler handler
+);
+
+extern int XMissingExtension(
+ Display* /* dpy */,
+ _Xconst char* /* ext_name */
+);
+
+_XFUNCPROTOEND
+
+#define X_EXTENSION_UNKNOWN "unknown"
+#define X_EXTENSION_MISSING "missing"
+
+#endif /* _XEXT_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/Xinerama.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xinerama.h
new file mode 100644
index 0000000..54f2fe1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xinerama.h
@@ -0,0 +1,46 @@
+/* $XFree86: xc/include/extensions/Xinerama.h,v 3.2 2000/03/01 01:04:20 dawes Exp $ */
+
+#ifndef _Xinerama_h
+#define _Xinerama_h
+
+#include "SDL_name.h"
+
+typedef struct {
+ int screen_number;
+ short x_org;
+ short y_org;
+ short width;
+ short height;
+} SDL_NAME(XineramaScreenInfo);
+
+Bool SDL_NAME(XineramaQueryExtension) (
+ Display *dpy,
+ int *event_base,
+ int *error_base
+);
+
+Status SDL_NAME(XineramaQueryVersion)(
+ Display *dpy,
+ int *major,
+ int *minor
+);
+
+Bool SDL_NAME(XineramaIsActive)(Display *dpy);
+
+
+/*
+ Returns the number of heads and a pointer to an array of
+ structures describing the position and size of the individual
+ heads. Returns NULL and number = 0 if Xinerama is not active.
+
+ Returned array should be freed with XFree().
+*/
+
+SDL_NAME(XineramaScreenInfo) *
+SDL_NAME(XineramaQueryScreens)(
+ Display *dpy,
+ int *number
+);
+
+#endif /* _Xinerama_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/Xv.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xv.h
new file mode 100644
index 0000000..a6a0271
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xv.h
@@ -0,0 +1,129 @@
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/include/extensions/Xv.h,v 1.5 1999/12/11 19:28:48 mvojkovi Exp $ */
+
+#ifndef XV_H
+#define XV_H
+/*
+** File:
+**
+** Xv.h --- Xv shared library and server header file
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 05.15.91 Carver
+** - version 2.0 upgrade
+**
+** 01.24.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#include <X11/X.h>
+
+#define XvName "XVideo"
+#define XvVersion 2
+#define XvRevision 2
+
+/* Symbols */
+
+typedef XID XvPortID;
+typedef XID XvEncodingID;
+
+#define XvNone 0
+
+#define XvInput 0
+#define XvOutput 1
+
+#define XvInputMask (1L<<XvInput)
+#define XvOutputMask (1L<<XvOutput)
+#define XvVideoMask 0x00000004
+#define XvStillMask 0x00000008
+#define XvImageMask 0x00000010
+
+/* These two are not client viewable */
+#define XvPixmapMask 0x00010000
+#define XvWindowMask 0x00020000
+
+
+#define XvGettable 0x01
+#define XvSettable 0x02
+
+#define XvRGB 0
+#define XvYUV 1
+
+#define XvPacked 0
+#define XvPlanar 1
+
+#define XvTopToBottom 0
+#define XvBottomToTop 1
+
+
+/* Events */
+
+#define XvVideoNotify 0
+#define XvPortNotify 1
+#define XvNumEvents 2
+
+/* Video Notify Reasons */
+
+#define XvStarted 0
+#define XvStopped 1
+#define XvBusy 2
+#define XvPreempted 3
+#define XvHardError 4
+#define XvLastReason 4
+
+#define XvNumReasons (XvLastReason + 1)
+
+#define XvStartedMask (1L<<XvStarted)
+#define XvStoppedMask (1L<<XvStopped)
+#define XvBusyMask (1L<<XvBusy)
+#define XvPreemptedMask (1L<<XvPreempted)
+#define XvHardErrorMask (1L<<XvHardError)
+
+#define XvAnyReasonMask ((1L<<XvNumReasons) - 1)
+#define XvNoReasonMask 0
+
+/* Errors */
+
+#define XvBadPort 0
+#define XvBadEncoding 1
+#define XvBadControl 2
+#define XvNumErrors 3
+
+/* Status */
+
+#define XvBadExtension 1
+#define XvAlreadyGrabbed 2
+#define XvInvalidTime 3
+#define XvBadReply 4
+#define XvBadAlloc 5
+
+#endif /* XV_H */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvlib.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvlib.h
new file mode 100644
index 0000000..0d0a55d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvlib.h
@@ -0,0 +1,433 @@
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/include/extensions/Xvlib.h,v 1.3 1999/12/11 19:28:48 mvojkovi Exp $ */
+
+#ifndef XVLIB_H
+#define XVLIB_H
+/*
+** File:
+**
+** Xvlib.h --- Xv library public header file
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 26.06.91 Carver
+** - changed XvFreeAdaptors to XvFreeAdaptorInfo
+** - changed XvFreeEncodings to XvFreeEncodingInfo
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 05.15.91 Carver
+** - version 2.0 upgrade
+**
+** 01.24.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#include <X11/Xfuncproto.h>
+#include "Xv.h"
+#include "SDL_name.h"
+
+typedef struct {
+ int numerator;
+ int denominator;
+} SDL_NAME(XvRational);
+
+typedef struct {
+ int flags; /* XvGettable, XvSettable */
+ int min_value;
+ int max_value;
+ char *name;
+} SDL_NAME(XvAttribute);
+
+typedef struct {
+ XvEncodingID encoding_id;
+ char *name;
+ unsigned long width;
+ unsigned long height;
+ SDL_NAME(XvRational) rate;
+ unsigned long num_encodings;
+} SDL_NAME(XvEncodingInfo);
+
+typedef struct {
+ char depth;
+ unsigned long visual_id;
+} SDL_NAME(XvFormat);
+
+typedef struct {
+ XvPortID base_id;
+ unsigned long num_ports;
+ char type;
+ char *name;
+ unsigned long num_formats;
+ SDL_NAME(XvFormat) *formats;
+ unsigned long num_adaptors;
+} SDL_NAME(XvAdaptorInfo);
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Drawable drawable; /* drawable */
+ unsigned long reason; /* what generated this event */
+ XvPortID port_id; /* what port */
+ Time time; /* milliseconds */
+} SDL_NAME(XvVideoNotifyEvent);
+
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ XvPortID port_id; /* what port */
+ Time time; /* milliseconds */
+ Atom attribute; /* atom that identifies attribute */
+ long value; /* value of attribute */
+} SDL_NAME(XvPortNotifyEvent);
+
+typedef union {
+ int type;
+ SDL_NAME(XvVideoNotifyEvent) xvvideo;
+ SDL_NAME(XvPortNotifyEvent) xvport;
+ long pad[24];
+} SDL_NAME(XvEvent);
+
+typedef struct {
+ int id; /* Unique descriptor for the format */
+ int type; /* XvRGB, XvYUV */
+ int byte_order; /* LSBFirst, MSBFirst */
+ char guid[16]; /* Globally Unique IDentifier */
+ int bits_per_pixel;
+ int format; /* XvPacked, XvPlanar */
+ int num_planes;
+
+ /* for RGB formats only */
+ int depth;
+ unsigned int red_mask;
+ unsigned int green_mask;
+ unsigned int blue_mask;
+
+ /* for YUV formats only */
+ unsigned int y_sample_bits;
+ unsigned int u_sample_bits;
+ unsigned int v_sample_bits;
+ unsigned int horz_y_period;
+ unsigned int horz_u_period;
+ unsigned int horz_v_period;
+ unsigned int vert_y_period;
+ unsigned int vert_u_period;
+ unsigned int vert_v_period;
+ char component_order[32]; /* eg. UYVY */
+ int scanline_order; /* XvTopToBottom, XvBottomToTop */
+} SDL_NAME(XvImageFormatValues);
+
+typedef struct {
+ int id;
+ int width, height;
+ int data_size; /* bytes */
+ int num_planes;
+ int *pitches; /* bytes */
+ int *offsets; /* bytes */
+ char *data;
+ XPointer obdata;
+} SDL_NAME(XvImage);
+
+_XFUNCPROTOBEGIN
+
+extern int SDL_NAME(XvQueryExtension)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int* /* p_version */,
+ unsigned int* /* p_revision */,
+ unsigned int* /* p_requestBase */,
+ unsigned int* /* p_eventBase */,
+ unsigned int* /* p_errorBase */
+#endif
+);
+
+extern int SDL_NAME(XvQueryAdaptors)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Window /* window */,
+ unsigned int* /* p_nAdaptors */,
+ SDL_NAME(XvAdaptorInfo)** /* p_pAdaptors */
+#endif
+);
+
+extern int SDL_NAME(XvQueryEncodings)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ unsigned int* /* p_nEncoding */,
+ SDL_NAME(XvEncodingInfo)** /* p_pEncoding */
+#endif
+);
+
+extern int SDL_NAME(XvPutVideo)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* vx */,
+ int /* vy */,
+ unsigned int /* vw */,
+ unsigned int /* vh */,
+ int /* dx */,
+ int /* dy */,
+ unsigned int /* dw */,
+ unsigned int /* dh */
+#endif
+);
+
+extern int SDL_NAME(XvPutStill)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* vx */,
+ int /* vy */,
+ unsigned int /* vw */,
+ unsigned int /* vh */,
+ int /* dx */,
+ int /* dy */,
+ unsigned int /* dw */,
+ unsigned int /* dh */
+#endif
+);
+
+extern int SDL_NAME(XvGetVideo)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* vx */,
+ int /* vy */,
+ unsigned int /* vw */,
+ unsigned int /* vh */,
+ int /* dx */,
+ int /* dy */,
+ unsigned int /* dw */,
+ unsigned int /* dh */
+#endif
+);
+
+extern int SDL_NAME(XvGetStill)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Drawable /* d */,
+ GC /* gc */,
+ int /* vx */,
+ int /* vy */,
+ unsigned int /* vw */,
+ unsigned int /* vh */,
+ int /* dx */,
+ int /* dy */,
+ unsigned int /* dw */,
+ unsigned int /* dh */
+#endif
+);
+
+extern int SDL_NAME(XvStopVideo)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Drawable /* drawable */
+#endif
+);
+
+extern int SDL_NAME(XvGrabPort)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Time /* time */
+#endif
+);
+
+extern int SDL_NAME(XvUngrabPort)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Time /* time */
+#endif
+);
+
+extern int SDL_NAME(XvSelectVideoNotify)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Drawable /* drawable */,
+ Bool /* onoff */
+#endif
+);
+
+extern int SDL_NAME(XvSelectPortNotify)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Bool /* onoff */
+#endif
+);
+
+extern int SDL_NAME(XvSetPortAttribute)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Atom /* attribute */,
+ int /* value */
+#endif
+);
+
+extern int SDL_NAME(XvGetPortAttribute)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Atom /* attribute */,
+ int* /* p_value */
+#endif
+);
+
+extern int SDL_NAME(XvQueryBestSize)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ Bool /* motion */,
+ unsigned int /* vid_w */,
+ unsigned int /* vid_h */,
+ unsigned int /* drw_w */,
+ unsigned int /* drw_h */,
+ unsigned int* /* p_actual_width */,
+ unsigned int* /* p_actual_width */
+#endif
+);
+
+extern SDL_NAME(XvAttribute)* SDL_NAME(XvQueryPortAttributes)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XvPortID /* port */,
+ int* /* number */
+#endif
+);
+
+
+extern void SDL_NAME(XvFreeAdaptorInfo)(
+#if NeedFunctionPrototypes
+ SDL_NAME(XvAdaptorInfo)* /* adaptors */
+#endif
+);
+
+extern void SDL_NAME(XvFreeEncodingInfo)(
+#if NeedFunctionPrototypes
+ SDL_NAME(XvEncodingInfo)* /* encodings */
+#endif
+);
+
+
+extern SDL_NAME(XvImageFormatValues) * SDL_NAME(XvListImageFormats) (
+#if NeedFunctionPrototypes
+ Display *display,
+ XvPortID port_id,
+ int *count_return
+#endif
+);
+
+extern SDL_NAME(XvImage) * SDL_NAME(XvCreateImage) (
+#if NeedFunctionPrototypes
+ Display *display,
+ XvPortID port,
+ int id,
+ char *data,
+ int width,
+ int height
+#endif
+);
+
+extern int SDL_NAME(XvPutImage) (
+#if NeedFunctionPrototypes
+ Display *display,
+ XvPortID id,
+ Drawable d,
+ GC gc,
+ SDL_NAME(XvImage) *image,
+ int src_x,
+ int src_y,
+ unsigned int src_w,
+ unsigned int src_h,
+ int dest_x,
+ int dest_y,
+ unsigned int dest_w,
+ unsigned int dest_h
+#endif
+);
+
+extern int SDL_NAME(XvShmPutImage) (
+#if NeedFunctionPrototypes
+ Display *display,
+ XvPortID id,
+ Drawable d,
+ GC gc,
+ SDL_NAME(XvImage) *image,
+ int src_x,
+ int src_y,
+ unsigned int src_w,
+ unsigned int src_h,
+ int dest_x,
+ int dest_y,
+ unsigned int dest_w,
+ unsigned int dest_h,
+ Bool send_event
+#endif
+);
+
+#ifdef _XSHM_H_
+
+extern SDL_NAME(XvImage) * SDL_NAME(XvShmCreateImage) (
+#if NeedFunctionPrototypes
+ Display *display,
+ XvPortID port,
+ int id,
+ char* data,
+ int width,
+ int height,
+ XShmSegmentInfo *shminfo
+#endif
+);
+
+#endif
+
+
+_XFUNCPROTOEND
+
+#endif /* XVLIB_H */
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvproto.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvproto.h
new file mode 100644
index 0000000..b4d8f22
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/Xvproto.h
@@ -0,0 +1,604 @@
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/include/extensions/Xvproto.h,v 1.6 2001/05/07 21:37:12 tsi Exp $ */
+
+#ifndef XVPROTO_H
+#define XVPROTO_H
+/*
+** File:
+**
+** Xvproto.h --- Xv protocol header file
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 24.01.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#include <X11/Xmd.h>
+
+/* Symbols: These are undefined at the end of this file to restore the
+ values they have in Xv.h */
+
+#define XvPortID CARD32
+#define XvEncodingID CARD32
+#define ShmSeg CARD32
+#define VisualID CARD32
+#define Drawable CARD32
+#define GContext CARD32
+#define Time CARD32
+#define Atom CARD32
+
+/* Structures */
+
+typedef struct {
+ INT32 numerator B32;
+ INT32 denominator B32;
+} xvRational;
+#define sz_xvRational 8
+
+typedef struct {
+ XvPortID base_id B32;
+ CARD16 name_size B16;
+ CARD16 num_ports B16;
+ CARD16 num_formats B16;
+ CARD8 type;
+ CARD8 pad;
+} xvAdaptorInfo;
+#define sz_xvAdaptorInfo 12
+
+typedef struct {
+ XvEncodingID encoding B32;
+ CARD16 name_size B16;
+ CARD16 width B16, height B16;
+ xvRational rate;
+ CARD16 pad B16;
+} xvEncodingInfo;
+#define sz_xvEncodingInfo (12 + sz_xvRational)
+
+typedef struct {
+ VisualID visual B32;
+ CARD8 depth;
+ CARD8 pad1;
+ CARD16 pad2 B16;
+} xvFormat;
+#define sz_xvFormat 8
+
+typedef struct {
+ CARD32 flags B32;
+ INT32 min B32;
+ INT32 max B32;
+ CARD32 size B32;
+} xvAttributeInfo;
+#define sz_xvAttributeInfo 16
+
+typedef struct {
+ CARD32 id B32;
+ CARD8 type;
+ CARD8 byte_order;
+ CARD16 pad1 B16;
+ CARD8 guid[16];
+ CARD8 bpp;
+ CARD8 num_planes;
+ CARD16 pad2 B16;
+ CARD8 depth;
+ CARD8 pad3;
+ CARD16 pad4 B16;
+ CARD32 red_mask B32;
+ CARD32 green_mask B32;
+ CARD32 blue_mask B32;
+ CARD8 format;
+ CARD8 pad5;
+ CARD16 pad6 B16;
+ CARD32 y_sample_bits B32;
+ CARD32 u_sample_bits B32;
+ CARD32 v_sample_bits B32;
+ CARD32 horz_y_period B32;
+ CARD32 horz_u_period B32;
+ CARD32 horz_v_period B32;
+ CARD32 vert_y_period B32;
+ CARD32 vert_u_period B32;
+ CARD32 vert_v_period B32;
+ CARD8 comp_order[32];
+ CARD8 scanline_order;
+ CARD8 pad7;
+ CARD16 pad8 B16;
+ CARD32 pad9 B32;
+ CARD32 pad10 B32;
+} xvImageFormatInfo;
+#define sz_xvImageFormatInfo 128
+
+
+/* Requests */
+
+#define xv_QueryExtension 0
+#define xv_QueryAdaptors 1
+#define xv_QueryEncodings 2
+#define xv_GrabPort 3
+#define xv_UngrabPort 4
+#define xv_PutVideo 5
+#define xv_PutStill 6
+#define xv_GetVideo 7
+#define xv_GetStill 8
+#define xv_StopVideo 9
+#define xv_SelectVideoNotify 10
+#define xv_SelectPortNotify 11
+#define xv_QueryBestSize 12
+#define xv_SetPortAttribute 13
+#define xv_GetPortAttribute 14
+#define xv_QueryPortAttributes 15
+#define xv_ListImageFormats 16
+#define xv_QueryImageAttributes 17
+#define xv_PutImage 18
+#define xv_ShmPutImage 19
+#define xv_LastRequest xv_ShmPutImage
+
+#define xvNumRequests (xv_LastRequest + 1)
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+} xvQueryExtensionReq;
+#define sz_xvQueryExtensionReq 4
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ CARD32 window B32;
+} xvQueryAdaptorsReq;
+#define sz_xvQueryAdaptorsReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ CARD32 port B32;
+} xvQueryEncodingsReq;
+#define sz_xvQueryEncodingsReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ INT16 vid_x B16;
+ INT16 vid_y B16;
+ CARD16 vid_w B16;
+ CARD16 vid_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+} xvPutVideoReq;
+#define sz_xvPutVideoReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ INT16 vid_x B16;
+ INT16 vid_y B16;
+ CARD16 vid_w B16;
+ CARD16 vid_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+} xvPutStillReq;
+#define sz_xvPutStillReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ INT16 vid_x B16;
+ INT16 vid_y B16;
+ CARD16 vid_w B16;
+ CARD16 vid_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+} xvGetVideoReq;
+#define sz_xvGetVideoReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ INT16 vid_x B16;
+ INT16 vid_y B16;
+ CARD16 vid_w B16;
+ CARD16 vid_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+} xvGetStillReq;
+#define sz_xvGetStillReq 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Time time B32;
+} xvGrabPortReq;
+#define sz_xvGrabPortReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Time time B32;
+} xvUngrabPortReq;
+#define sz_xvUngrabPortReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ Drawable drawable B32;
+ BOOL onoff;
+ CARD8 pad1;
+ CARD16 pad2;
+} xvSelectVideoNotifyReq;
+#define sz_xvSelectVideoNotifyReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ BOOL onoff;
+ CARD8 pad1;
+ CARD16 pad2;
+} xvSelectPortNotifyReq;
+#define sz_xvSelectPortNotifyReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+} xvStopVideoReq;
+#define sz_xvStopVideoReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Atom attribute B32;
+ INT32 value B32;
+} xvSetPortAttributeReq;
+#define sz_xvSetPortAttributeReq 16
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Atom attribute B32;
+} xvGetPortAttributeReq;
+#define sz_xvGetPortAttributeReq 12
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ CARD16 vid_w B16;
+ CARD16 vid_h B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+ CARD8 motion;
+ CARD8 pad1;
+ CARD16 pad2 B16;
+} xvQueryBestSizeReq;
+#define sz_xvQueryBestSizeReq 20
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+} xvQueryPortAttributesReq;
+#define sz_xvQueryPortAttributesReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ CARD32 id B32;
+ INT16 src_x B16;
+ INT16 src_y B16;
+ CARD16 src_w B16;
+ CARD16 src_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+ CARD16 width B16;
+ CARD16 height B16;
+} xvPutImageReq;
+#define sz_xvPutImageReq 40
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+ Drawable drawable B32;
+ GContext gc B32;
+ ShmSeg shmseg B32;
+ CARD32 id B32;
+ CARD32 offset B32;
+ INT16 src_x B16;
+ INT16 src_y B16;
+ CARD16 src_w B16;
+ CARD16 src_h B16;
+ INT16 drw_x B16;
+ INT16 drw_y B16;
+ CARD16 drw_w B16;
+ CARD16 drw_h B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD8 send_event;
+ CARD8 pad1;
+ CARD16 pad2 B16;
+} xvShmPutImageReq;
+#define sz_xvShmPutImageReq 52
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ XvPortID port B32;
+} xvListImageFormatsReq;
+#define sz_xvListImageFormatsReq 8
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvReqType;
+ CARD16 length B16;
+ CARD32 port B32;
+ CARD32 id B32;
+ CARD16 width B16;
+ CARD16 height B16;
+} xvQueryImageAttributesReq;
+#define sz_xvQueryImageAttributesReq 16
+
+
+/* Replies */
+
+typedef struct _QueryExtensionReply {
+ BYTE type; /* X_Reply */
+ CARD8 padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 version B16;
+ CARD16 revision B16;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryExtensionReply;
+#define sz_xvQueryExtensionReply 32
+
+typedef struct _QueryAdaptorsReply {
+ BYTE type; /* X_Reply */
+ CARD8 padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 num_adaptors B16;
+ CARD16 pads3 B16;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryAdaptorsReply;
+#define sz_xvQueryAdaptorsReply 32
+
+typedef struct _QueryEncodingsReply {
+ BYTE type; /* X_Reply */
+ CARD8 padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 num_encodings B16;
+ CARD32 padl3 B32;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryEncodingsReply;
+#define sz_xvQueryEncodingsReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE result;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32; /* 0 */
+ CARD32 padl3 B32;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvGrabPortReply;
+#define sz_xvGrabPortReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32; /* 0 */
+ INT32 value B32;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvGetPortAttributeReply;
+#define sz_xvGetPortAttributeReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32; /* 0 */
+ CARD16 actual_width B16;
+ CARD16 actual_height B16;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryBestSizeReply;
+#define sz_xvQueryBestSizeReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32; /* 0 */
+ CARD32 num_attributes B32;
+ CARD32 text_size B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryPortAttributesReply;
+#define sz_xvQueryPortAttributesReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 num_formats B32;
+ CARD32 padl4 B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvListImageFormatsReply;
+#define sz_xvListImageFormatsReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 num_planes B32;
+ CARD32 data_size B32;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+} xvQueryImageAttributesReply;
+#define sz_xvQueryImageAttributesReply 32
+
+/* DEFINE EVENT STRUCTURE */
+
+typedef struct {
+ union {
+ struct {
+ BYTE type;
+ BYTE detail;
+ CARD16 sequenceNumber B16;
+ } u;
+ struct {
+ BYTE type;
+ BYTE reason;
+ CARD16 sequenceNumber B16;
+ Time time B32;
+ Drawable drawable B32;
+ XvPortID port B32;
+ CARD32 padl5 B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+ } videoNotify;
+ struct {
+ BYTE type;
+ BYTE padb1;
+ CARD16 sequenceNumber B16;
+ Time time B32;
+ XvPortID port B32;
+ Atom attribute B32;
+ INT32 value B32;
+ CARD32 padl6 B32;
+ CARD32 padl7 B32;
+ CARD32 padl8 B32;
+ } portNotify;
+ } u;
+} xvEvent;
+
+#undef XvPortID
+#undef XvEncodingID
+#undef ShmSeg
+#undef VisualID
+#undef Drawable
+#undef GContext
+#undef Time
+#undef Atom
+
+#endif /* XVPROTO_H */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/extutil.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/extutil.h
new file mode 100644
index 0000000..f3a741e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/extutil.h
@@ -0,0 +1,226 @@
+/*
+ * $Xorg: extutil.h,v 1.4 2001/02/09 02:03:24 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Jim Fulton, MIT The Open Group
+ *
+ * Xlib Extension-Writing Utilities
+ *
+ * This package contains utilities for writing the client API for various
+ * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
+ * ARE SUBJECT TO CHANGE!
+ */
+/* $XFree86: xc/include/extensions/extutil.h,v 1.9 2001/12/14 19:53:28 dawes Exp $ */
+
+#ifndef _EXTUTIL_H_
+#define _EXTUTIL_H_
+
+#include "SDL_stdinc.h" /* For portable string functions */
+
+#include "./Xext.h"
+
+/*
+ * We need to keep a list of open displays since the Xlib display list isn't
+ * public. We also have to per-display info in a separate block since it isn't
+ * stored directly in the Display structure.
+ */
+typedef struct _XExtDisplayInfo {
+ struct _XExtDisplayInfo *next; /* keep a linked list */
+ Display *display; /* which display this is */
+ XExtCodes *codes; /* the extension protocol codes */
+ XPointer data; /* extra data for extension to use */
+} XExtDisplayInfo;
+
+typedef struct _XExtensionInfo {
+ XExtDisplayInfo *head; /* start of list */
+ XExtDisplayInfo *cur; /* most recently used */
+ int ndisplays; /* number of displays */
+} XExtensionInfo;
+
+typedef struct _XExtensionHooks {
+ int (*create_gc)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*copy_gc)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*flush_gc)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*free_gc)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ GC /* gc */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*create_font)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*free_font)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ XFontStruct* /* fs */,
+ XExtCodes* /* codes */
+#endif
+);
+ int (*close_display)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ XExtCodes* /* codes */
+#endif
+);
+ Bool (*wire_to_event)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+#endif
+);
+ Status (*event_to_wire)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ XEvent* /* re */,
+ xEvent* /* event */
+#endif
+);
+ int (*error)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ xError* /* err */,
+ XExtCodes* /* codes */,
+ int* /* ret_code */
+#endif
+);
+ char *(*error_string)(
+#if NeedNestedPrototypes
+ Display* /* display */,
+ int /* code */,
+ XExtCodes* /* codes */,
+ char* /* buffer */,
+ int /* nbytes */
+#endif
+);
+} XExtensionHooks;
+
+extern XExtensionInfo *XextCreateExtension(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+extern void XextDestroyExtension(
+#if NeedFunctionPrototypes
+ XExtensionInfo* /* info */
+#endif
+);
+extern XExtDisplayInfo *XextAddDisplay(
+#if NeedFunctionPrototypes
+ XExtensionInfo* /* extinfo */,
+ Display* /* dpy */,
+ char* /* ext_name */,
+ XExtensionHooks* /* hooks */,
+ int /* nevents */,
+ XPointer /* data */
+#endif
+);
+extern int XextRemoveDisplay(
+#if NeedFunctionPrototypes
+ XExtensionInfo* /* extinfo */,
+ Display* /* dpy */
+#endif
+);
+extern XExtDisplayInfo *XextFindDisplay(
+#if NeedFunctionPrototypes
+ XExtensionInfo* /* extinfo */,
+ Display* /* dpy */
+#endif
+);
+
+#define XextHasExtension(i) ((i) && ((i)->codes))
+#define XextCheckExtension(dpy,i,name,val) \
+ if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; }
+#define XextSimpleCheckExtension(dpy,i,name) \
+ if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; }
+
+
+/*
+ * helper macros to generate code that is common to all extensions; caller
+ * should prefix it with static if extension source is in one file; this
+ * could be a utility function, but have to stack 6 unused arguments for
+ * something that is called many, many times would be bad.
+ */
+#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \
+XExtDisplayInfo *proc (Display *dpy) \
+{ \
+ XExtDisplayInfo *dpyinfo; \
+ if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \
+ if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \
+ dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \
+ return dpyinfo; \
+}
+
+#define XEXT_FIND_DISPLAY_PROTO(proc) \
+ XExtDisplayInfo *proc(Display *dpy)
+
+#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \
+int proc (Display *dpy, XExtCodes *codes) \
+{ \
+ return XextRemoveDisplay (extinfo, dpy); \
+}
+
+#define XEXT_CLOSE_DISPLAY_PROTO(proc) \
+ int proc(Display *dpy, XExtCodes *codes)
+
+#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \
+char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \
+{ \
+ code -= codes->first_error; \
+ if (code >= 0 && code < nerr) { \
+ char tmp[256]; \
+ SDL_snprintf (tmp, SDL_arraysize(tmp), "%s.%d", extname, code); \
+ XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \
+ return buf; \
+ } \
+ return (char *)0; \
+}
+
+#define XEXT_ERROR_STRING_PROTO(proc) \
+ char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n)
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXext.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXext.h
new file mode 100644
index 0000000..e89d891
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXext.h
@@ -0,0 +1,52 @@
+/* $Xorg: panoramiXext.h,v 1.4 2000/08/18 04:05:45 coskrey Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+/*
+ * PanoramiX definitions
+ */
+/* $XFree86: xc/include/extensions/panoramiXext.h,v 3.6 2001/01/17 17:53:22 dawes Exp $ */
+
+#include "SDL_name.h"
+
+/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
+
+#define PANORAMIX_MAJOR_VERSION 1 /* current version number */
+#define PANORAMIX_MINOR_VERSION 1
+
+typedef struct {
+ Window window; /* PanoramiX window - may not exist */
+ int screen;
+ int State; /* PanroamiXOff, PanoramiXOn */
+ int width; /* width of this screen */
+ int height; /* height of this screen */
+ int ScreenCount; /* real physical number of screens */
+ XID eventMask; /* selected events for this client */
+} SDL_NAME(XPanoramiXInfo);
+
+extern SDL_NAME(XPanoramiXInfo) *SDL_NAME(XPanoramiXAllocInfo) (
+#if NeedFunctionPrototypes
+ void
+#endif
+);
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXproto.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXproto.h
new file mode 100644
index 0000000..fe3826e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/panoramiXproto.h
@@ -0,0 +1,192 @@
+/* $Xorg: panoramiXproto.h,v 1.4 2000/08/18 04:05:45 coskrey Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+/* $XFree86: xc/include/extensions/panoramiXproto.h,v 3.6 2001/01/17 17:53:22 dawes Exp $ */
+
+/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
+
+#ifndef _PANORAMIXPROTO_H_
+#define _PANORAMIXPROTO_H_
+
+#define PANORAMIX_PROTOCOL_NAME "XINERAMA"
+
+#define X_PanoramiXQueryVersion 0
+#define X_PanoramiXGetState 1
+#define X_PanoramiXGetScreenCount 2
+#define X_PanoramiXGetScreenSize 3
+
+#define X_XineramaIsActive 4
+#define X_XineramaQueryScreens 5
+
+typedef struct _PanoramiXQueryVersion {
+ CARD8 reqType; /* always PanoramiXReqCode */
+ CARD8 panoramiXReqType; /* always X_PanoramiXQueryVersion */
+ CARD16 length B16;
+ CARD8 clientMajor;
+ CARD8 clientMinor;
+ CARD16 unused B16;
+} xPanoramiXQueryVersionReq;
+
+#define sz_xPanoramiXQueryVersionReq 8
+
+typedef struct {
+ CARD8 type; /* must be X_Reply */
+ CARD8 pad1; /* unused */
+ CARD16 sequenceNumber B16; /* last sequence number */
+ CARD32 length B32; /* 0 */
+ CARD16 majorVersion B16;
+ CARD16 minorVersion B16;
+ CARD32 pad2 B32; /* unused */
+ CARD32 pad3 B32; /* unused */
+ CARD32 pad4 B32; /* unused */
+ CARD32 pad5 B32; /* unused */
+ CARD32 pad6 B32; /* unused */
+} xPanoramiXQueryVersionReply;
+
+#define sz_xPanoramiXQueryVersionReply 32
+
+
+typedef struct _PanoramiXGetState {
+ CARD8 reqType; /* always PanoramiXReqCode */
+ CARD8 panoramiXReqType; /* always X_PanoramiXGetState */
+ CARD16 length B16;
+ CARD32 window B32;
+} xPanoramiXGetStateReq;
+#define sz_xPanoramiXGetStateReq 8
+
+typedef struct {
+ BYTE type;
+ BYTE state;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 window B32;
+ CARD32 pad1 B32; /* unused */
+ CARD32 pad2 B32; /* unused */
+ CARD32 pad3 B32; /* unused */
+ CARD32 pad4 B32; /* unused */
+ CARD32 pad5 B32; /* unused */
+} xPanoramiXGetStateReply;
+
+#define sz_panoramiXGetStateReply 32
+
+typedef struct _PanoramiXGetScreenCount {
+ CARD8 reqType; /* always PanoramiXReqCode */
+ CARD8 panoramiXReqType; /* always X_PanoramiXGetScreenCount */
+ CARD16 length B16;
+ CARD32 window B32;
+} xPanoramiXGetScreenCountReq;
+#define sz_xPanoramiXGetScreenCountReq 8
+
+typedef struct {
+ BYTE type;
+ BYTE ScreenCount;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 window B32;
+ CARD32 pad1 B32; /* unused */
+ CARD32 pad2 B32; /* unused */
+ CARD32 pad3 B32; /* unused */
+ CARD32 pad4 B32; /* unused */
+ CARD32 pad5 B32; /* unused */
+} xPanoramiXGetScreenCountReply;
+#define sz_panoramiXGetScreenCountReply 32
+
+typedef struct _PanoramiXGetScreenSize {
+ CARD8 reqType; /* always PanoramiXReqCode */
+ CARD8 panoramiXReqType; /* always X_PanoramiXGetState */
+ CARD16 length B16;
+ CARD32 window B32;
+ CARD32 screen B32;
+} xPanoramiXGetScreenSizeReq;
+#define sz_xPanoramiXGetScreenSizeReq 12
+
+typedef struct {
+ BYTE type;
+ CARD8 pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 width B32;
+ CARD32 height B32;
+ CARD32 window B32;
+ CARD32 screen B32;
+ CARD32 pad2 B32; /* unused */
+ CARD32 pad3 B32; /* unused */
+} xPanoramiXGetScreenSizeReply;
+#define sz_panoramiXGetScreenSizeReply 32
+
+/************ Alternate protocol ******************/
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 panoramiXReqType;
+ CARD16 length B16;
+} xXineramaIsActiveReq;
+#define sz_xXineramaIsActiveReq 4
+
+typedef struct {
+ BYTE type;
+ CARD8 pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 state B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXineramaIsActiveReply;
+#define sz_XineramaIsActiveReply 32
+
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 panoramiXReqType;
+ CARD16 length B16;
+} xXineramaQueryScreensReq;
+#define sz_xXineramaQueryScreensReq 4
+
+typedef struct {
+ BYTE type;
+ CARD8 pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 number B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXineramaQueryScreensReply;
+#define sz_XineramaQueryScreensReply 32
+
+typedef struct {
+ INT16 x_org B16;
+ INT16 y_org B16;
+ CARD16 width B16;
+ CARD16 height B16;
+} xXineramaScreenInfo;
+#define sz_XineramaScreenInfo 8
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga.h
new file mode 100644
index 0000000..c71ef4b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga.h
@@ -0,0 +1,265 @@
+/*
+ Copyright (c) 1999 XFree86 Inc
+*/
+/* $XFree86: xc/include/extensions/xf86dga.h,v 3.21 2001/08/01 00:44:36 tsi Exp $ */
+
+#ifndef _XF86DGA_H_
+#define _XF86DGA_H_
+
+#include <X11/Xfuncproto.h>
+#include "xf86dga1.h"
+#include "SDL_name.h"
+
+#define X_XDGAQueryVersion 0
+
+/* 1 through 9 are in xf86dga1.h */
+
+/* 10 and 11 are reserved to avoid conflicts with rogue DGA extensions */
+
+#define X_XDGAQueryModes 12
+#define X_XDGASetMode 13
+#define X_XDGASetViewport 14
+#define X_XDGAInstallColormap 15
+#define X_XDGASelectInput 16
+#define X_XDGAFillRectangle 17
+#define X_XDGACopyArea 18
+#define X_XDGACopyTransparentArea 19
+#define X_XDGAGetViewportStatus 20
+#define X_XDGASync 21
+#define X_XDGAOpenFramebuffer 22
+#define X_XDGACloseFramebuffer 23
+#define X_XDGASetClientVersion 24
+#define X_XDGAChangePixmapMode 25
+#define X_XDGACreateColormap 26
+
+
+#define XDGAConcurrentAccess 0x00000001
+#define XDGASolidFillRect 0x00000002
+#define XDGABlitRect 0x00000004
+#define XDGABlitTransRect 0x00000008
+#define XDGAPixmap 0x00000010
+
+#define XDGAInterlaced 0x00010000
+#define XDGADoublescan 0x00020000
+
+#define XDGAFlipImmediate 0x00000001
+#define XDGAFlipRetrace 0x00000002
+
+#define XDGANeedRoot 0x00000001
+
+#define XF86DGANumberEvents 7
+
+#define XDGAPixmapModeLarge 0
+#define XDGAPixmapModeSmall 1
+
+#define XF86DGAClientNotLocal 0
+#define XF86DGANoDirectVideoMode 1
+#define XF86DGAScreenNotActive 2
+#define XF86DGADirectNotActivated 3
+#define XF86DGAOperationNotSupported 4
+#define XF86DGANumberErrors (XF86DGAOperationNotSupported + 1)
+
+
+typedef struct {
+ int num; /* A unique identifier for the mode (num > 0) */
+ char *name; /* name of mode given in the XF86Config */
+ float verticalRefresh;
+ int flags; /* DGA_CONCURRENT_ACCESS, etc... */
+ int imageWidth; /* linear accessible portion (pixels) */
+ int imageHeight;
+ int pixmapWidth; /* Xlib accessible portion (pixels) */
+ int pixmapHeight; /* both fields ignored if no concurrent access */
+ int bytesPerScanline;
+ int byteOrder; /* MSBFirst, LSBFirst */
+ int depth;
+ int bitsPerPixel;
+ unsigned long redMask;
+ unsigned long greenMask;
+ unsigned long blueMask;
+ short visualClass;
+ int viewportWidth;
+ int viewportHeight;
+ int xViewportStep; /* viewport position granularity */
+ int yViewportStep;
+ int maxViewportX; /* max viewport origin */
+ int maxViewportY;
+ int viewportFlags; /* types of page flipping possible */
+ int reserved1;
+ int reserved2;
+} SDL_NAME(XDGAMode);
+
+
+typedef struct {
+ SDL_NAME(XDGAMode) mode;
+ unsigned char *data;
+ Pixmap pixmap;
+} SDL_NAME(XDGADevice);
+
+
+#ifndef _XF86DGA_SERVER_
+_XFUNCPROTOBEGIN
+
+typedef struct {
+ int type;
+ unsigned long serial;
+ Display *display;
+ int screen;
+ Time time;
+ unsigned int state;
+ unsigned int button;
+} SDL_NAME(XDGAButtonEvent);
+
+typedef struct {
+ int type;
+ unsigned long serial;
+ Display *display;
+ int screen;
+ Time time;
+ unsigned int state;
+ unsigned int keycode;
+} SDL_NAME(XDGAKeyEvent);
+
+typedef struct {
+ int type;
+ unsigned long serial;
+ Display *display;
+ int screen;
+ Time time;
+ unsigned int state;
+ int dx;
+ int dy;
+} SDL_NAME(XDGAMotionEvent);
+
+typedef union {
+ int type;
+ SDL_NAME(XDGAButtonEvent) xbutton;
+ SDL_NAME(XDGAKeyEvent) xkey;
+ SDL_NAME(XDGAMotionEvent) xmotion;
+ long pad[24];
+} SDL_NAME(XDGAEvent);
+
+Bool SDL_NAME(XDGAQueryExtension)(
+ Display *dpy,
+ int *eventBase,
+ int *erroBase
+);
+
+Bool SDL_NAME(XDGAQueryVersion)(
+ Display *dpy,
+ int *majorVersion,
+ int *minorVersion
+);
+
+SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
+ Display *dpy,
+ int screen,
+ int *num
+);
+
+SDL_NAME(XDGADevice)* SDL_NAME(XDGASetMode)(
+ Display *dpy,
+ int screen,
+ int mode
+);
+
+Bool SDL_NAME(XDGAOpenFramebuffer)(
+ Display *dpy,
+ int screen
+);
+
+void SDL_NAME(XDGACloseFramebuffer)(
+ Display *dpy,
+ int screen
+);
+
+void SDL_NAME(XDGASetViewport)(
+ Display *dpy,
+ int screen,
+ int x,
+ int y,
+ int flags
+);
+
+void SDL_NAME(XDGAInstallColormap)(
+ Display *dpy,
+ int screen,
+ Colormap cmap
+);
+
+Colormap SDL_NAME(XDGACreateColormap)(
+ Display *dpy,
+ int screen,
+ SDL_NAME(XDGADevice) *device,
+ int alloc
+);
+
+void SDL_NAME(XDGASelectInput)(
+ Display *dpy,
+ int screen,
+ long event_mask
+);
+
+void SDL_NAME(XDGAFillRectangle)(
+ Display *dpy,
+ int screen,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height,
+ unsigned long color
+);
+
+
+void SDL_NAME(XDGACopyArea)(
+ Display *dpy,
+ int screen,
+ int srcx,
+ int srcy,
+ unsigned int width,
+ unsigned int height,
+ int dstx,
+ int dsty
+);
+
+
+void SDL_NAME(XDGACopyTransparentArea)(
+ Display *dpy,
+ int screen,
+ int srcx,
+ int srcy,
+ unsigned int width,
+ unsigned int height,
+ int dstx,
+ int dsty,
+ unsigned long key
+);
+
+int SDL_NAME(XDGAGetViewportStatus)(
+ Display *dpy,
+ int screen
+);
+
+void SDL_NAME(XDGASync)(
+ Display *dpy,
+ int screen
+);
+
+Bool SDL_NAME(XDGASetClientVersion)(
+ Display *dpy
+);
+
+void SDL_NAME(XDGAChangePixmapMode)(
+ Display *dpy,
+ int screen,
+ int *x,
+ int *y,
+ int mode
+);
+
+
+void SDL_NAME(XDGAKeyEventToXKeyEvent)(SDL_NAME(XDGAKeyEvent)* dk, XKeyEvent* xk);
+
+
+_XFUNCPROTOEND
+#endif /* _XF86DGA_SERVER_ */
+#endif /* _XF86DGA_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1.h
new file mode 100644
index 0000000..4a49e9f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1.h
@@ -0,0 +1,169 @@
+/* $XFree86: xc/include/extensions/xf86dga1.h,v 1.2 1999/04/17 07:05:41 dawes Exp $ */
+/*
+
+Copyright (c) 1995 Jon Tombs
+Copyright (c) 1995 XFree86 Inc
+
+*/
+
+/************************************************************************
+
+ THIS IS THE OLD DGA API AND IS OBSOLETE. PLEASE DO NOT USE IT ANYMORE
+
+************************************************************************/
+
+#ifndef _XF86DGA1_H_
+#define _XF86DGA1_H_
+
+#include <X11/Xfuncproto.h>
+#include "SDL_name.h"
+
+#define X_XF86DGAQueryVersion 0
+#define X_XF86DGAGetVideoLL 1
+#define X_XF86DGADirectVideo 2
+#define X_XF86DGAGetViewPortSize 3
+#define X_XF86DGASetViewPort 4
+#define X_XF86DGAGetVidPage 5
+#define X_XF86DGASetVidPage 6
+#define X_XF86DGAInstallColormap 7
+#define X_XF86DGAQueryDirectVideo 8
+#define X_XF86DGAViewPortChanged 9
+
+#define XF86DGADirectPresent 0x0001
+#define XF86DGADirectGraphics 0x0002
+#define XF86DGADirectMouse 0x0004
+#define XF86DGADirectKeyb 0x0008
+#define XF86DGAHasColormap 0x0100
+#define XF86DGADirectColormap 0x0200
+
+
+
+
+#ifndef _XF86DGA_SERVER_
+
+_XFUNCPROTOBEGIN
+
+Bool SDL_NAME(XF86DGAQueryVersion)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int* /* majorVersion */,
+ int* /* minorVersion */
+#endif
+);
+
+Bool SDL_NAME(XF86DGAQueryExtension)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int* /* event_base */,
+ int* /* error_base */
+#endif
+);
+
+Status SDL_NAME(XF86DGAGetVideoLL)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int * /* base addr */,
+ int * /* width */,
+ int * /* bank_size */,
+ int * /* ram_size */
+#endif
+);
+
+Status SDL_NAME(XF86DGAGetVideo)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ char ** /* base addr */,
+ int * /* width */,
+ int * /* bank_size */,
+ int * /* ram_size */
+#endif
+);
+
+Status SDL_NAME(XF86DGADirectVideo)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int /* enable */
+#endif
+);
+
+Status SDL_NAME(XF86DGADirectVideoLL)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int /* enable */
+#endif
+);
+
+Status SDL_NAME(XF86DGAGetViewPortSize)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int * /* width */,
+ int * /* height */
+#endif
+);
+
+Status SDL_NAME(XF86DGASetViewPort)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int x /* X */,
+ int y /* Y */
+#endif
+);
+
+Status SDL_NAME(XF86DGAGetVidPage)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int * /* vid page */
+#endif
+);
+
+Status SDL_NAME(XF86DGASetVidPage)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ int /* vid page */
+#endif
+);
+
+Status SDL_NAME(XF86DGAInstallColormap)(
+#if NeedFunctionPrototypes
+ Display* /* dpy */,
+ int /* screen */,
+ Colormap /*Colormap */
+#endif
+);
+
+int SDL_NAME(XF86DGAForkApp)(
+#if NeedFunctionPrototypes
+ int screen
+#endif
+);
+
+Status SDL_NAME(XF86DGAQueryDirectVideo)(
+#if NeedFunctionPrototypes
+ Display * /* dpy */,
+ int /* screen */,
+ int * /* flags */
+#endif
+);
+
+Bool SDL_NAME(XF86DGAViewPortChanged)(
+#if NeedFunctionPrototypes
+ Display * /* dpy */,
+ int /* screen */,
+ int /* n */
+#endif
+);
+
+
+_XFUNCPROTOEND
+
+#endif /* _XF86DGA_SERVER_ */
+
+#endif /* _XF86DGA1_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1str.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1str.h
new file mode 100644
index 0000000..5695fbd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dga1str.h
@@ -0,0 +1,194 @@
+/* $XFree86: xc/include/extensions/xf86dga1str.h,v 1.2 1999/05/03 12:15:37 dawes Exp $ */
+/*
+
+Copyright (c) 1995 Jon Tombs
+Copyright (c) 1995 XFree86 Inc.
+
+*/
+
+#ifndef _XF86DGASTR1_H_
+#define _XF86DGASTR1_H_
+
+typedef struct _XF86DGAQueryVersion {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_DGAQueryVersion */
+ CARD16 length B16;
+} xXF86DGAQueryVersionReq;
+#define sz_xXF86DGAQueryVersionReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of DGA protocol */
+ CARD16 minorVersion B16; /* minor version of DGA protocol */
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86DGAQueryVersionReply;
+#define sz_xXF86DGAQueryVersionReply 32
+
+typedef struct _XF86DGAGetVideoLL {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGAGetVideoLL */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86DGAGetVideoLLReq;
+#define sz_xXF86DGAGetVideoLLReq 8
+
+typedef struct _XF86DGAInstallColormap{
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad2;
+ CARD32 id B32; /* colormap. */
+} xXF86DGAInstallColormapReq;
+#define sz_xXF86DGAInstallColormapReq 12
+
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 offset B32;
+ CARD32 width B32;
+ CARD32 bank_size B32;
+ CARD32 ram_size B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86DGAGetVideoLLReply;
+#define sz_xXF86DGAGetVideoLLReply 32
+
+typedef struct _XF86DGADirectVideo {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGADirectVideo */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 enable B16;
+} xXF86DGADirectVideoReq;
+#define sz_xXF86DGADirectVideoReq 8
+
+
+typedef struct _XF86DGAGetViewPortSize {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGAGetViewPort */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86DGAGetViewPortSizeReq;
+#define sz_xXF86DGAGetViewPortSizeReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 width B32;
+ CARD32 height B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86DGAGetViewPortSizeReply;
+#define sz_xXF86DGAGetViewPortSizeReply 32
+
+typedef struct _XF86DGASetViewPort {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGASetViewPort */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+ CARD32 x B32;
+ CARD32 y B32;
+} xXF86DGASetViewPortReq;
+#define sz_xXF86DGASetViewPortReq 16
+
+typedef struct _XF86DGAGetVidPage {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGAGetVidPage */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86DGAGetVidPageReq;
+#define sz_xXF86DGAGetVidPageReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 vpage B32;
+ CARD32 pad B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86DGAGetVidPageReply;
+#define sz_xXF86DGAGetVidPageReply 32
+
+
+typedef struct _XF86DGASetVidPage {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_XF86DGASetVidPage */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 vpage B16;
+} xXF86DGASetVidPageReq;
+#define sz_xXF86DGASetVidPageReq 8
+
+
+typedef struct _XF86DGAQueryDirectVideo {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_DGAQueryVersion */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86DGAQueryDirectVideoReq;
+#define sz_xXF86DGAQueryDirectVideoReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 flags B32;
+ CARD32 pad B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86DGAQueryDirectVideoReply;
+#define sz_xXF86DGAQueryDirectVideoReply 32
+
+
+typedef struct _XF86DGAViewPortChanged {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_DGAQueryVersion */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 n B16;
+} xXF86DGAViewPortChangedReq;
+#define sz_xXF86DGAViewPortChangedReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 result B32;
+ CARD32 pad B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86DGAViewPortChangedReply;
+#define sz_xXF86DGAViewPortChangedReply 32
+
+#endif /* _XF86DGASTR1_H_ */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dgastr.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dgastr.h
new file mode 100644
index 0000000..b249feb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86dgastr.h
@@ -0,0 +1,344 @@
+/* $XFree86: xc/include/extensions/xf86dgastr.h,v 3.14 2001/08/01 00:44:36 tsi Exp $ */
+/*
+
+Copyright (c) 1995 Jon Tombs
+Copyright (c) 1995 XFree86 Inc.
+
+*/
+
+#ifndef _XF86DGASTR_H_
+#define _XF86DGASTR_H_
+
+#include "xf86dga1str.h"
+
+#define XF86DGANAME "XFree86-DGA"
+
+#define XDGA_MAJOR_VERSION 2 /* current version numbers */
+#define XDGA_MINOR_VERSION 0
+
+
+typedef struct _XDGAQueryVersion {
+ CARD8 reqType; /* always DGAReqCode */
+ CARD8 dgaReqType; /* always X_DGAQueryVersion */
+ CARD16 length B16;
+} xXDGAQueryVersionReq;
+#define sz_xXDGAQueryVersionReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of DGA protocol */
+ CARD16 minorVersion B16; /* minor version of DGA protocol */
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXDGAQueryVersionReply;
+#define sz_xXDGAQueryVersionReply 32
+
+typedef struct _XDGAQueryModes {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXDGAQueryModesReq;
+#define sz_xXDGAQueryModesReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 number B32; /* number of modes available */
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXDGAQueryModesReply;
+#define sz_xXDGAQueryModesReply 32
+
+
+typedef struct _XDGASetMode {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 mode B32; /* mode number to init */
+ CARD32 pid B32; /* Pixmap descriptor */
+} xXDGASetModeReq;
+#define sz_xXDGASetModeReq 16
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 offset B32; /* offset into framebuffer map */
+ CARD32 flags B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXDGASetModeReply;
+#define sz_xXDGASetModeReply 32
+
+typedef struct {
+ CARD8 byte_order;
+ CARD8 depth;
+ CARD16 num B16;
+ CARD16 bpp B16;
+ CARD16 name_size B16;
+ CARD32 vsync_num B32;
+ CARD32 vsync_den B32;
+ CARD32 flags B32;
+ CARD16 image_width B16;
+ CARD16 image_height B16;
+ CARD16 pixmap_width B16;
+ CARD16 pixmap_height B16;
+ CARD32 bytes_per_scanline B32;
+ CARD32 red_mask B32;
+ CARD32 green_mask B32;
+ CARD32 blue_mask B32;
+ CARD16 visual_class B16;
+ CARD16 pad1 B16;
+ CARD16 viewport_width B16;
+ CARD16 viewport_height B16;
+ CARD16 viewport_xstep B16;
+ CARD16 viewport_ystep B16;
+ CARD16 viewport_xmax B16;
+ CARD16 viewport_ymax B16;
+ CARD32 viewport_flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+} xXDGAModeInfo;
+#define sz_xXDGAModeInfo 72
+
+typedef struct _XDGAOpenFramebuffer {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXDGAOpenFramebufferReq;
+#define sz_xXDGAOpenFramebufferReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32; /* device name size if there is one */
+ CARD32 mem1 B32; /* physical memory */
+ CARD32 mem2 B32; /* spillover for _alpha_ */
+ CARD32 size B32; /* size of map in bytes */
+ CARD32 offset B32; /* optional offset into device */
+ CARD32 extra B32; /* extra info associated with the map */
+ CARD32 pad2 B32;
+} xXDGAOpenFramebufferReply;
+#define sz_xXDGAOpenFramebufferReply 32
+
+
+typedef struct _XDGACloseFramebuffer {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXDGACloseFramebufferReq;
+#define sz_xXDGACloseFramebufferReq 8
+
+
+typedef struct _XDGASetViewport {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD16 x B16;
+ CARD16 y B16;
+ CARD32 flags B32;
+} xXDGASetViewportReq;
+#define sz_xXDGASetViewportReq 16
+
+
+typedef struct _XDGAInstallColormap {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 cmap B32;
+} xXDGAInstallColormapReq;
+#define sz_xXDGAInstallColormapReq 12
+
+typedef struct _XDGASelectInput {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 mask B32;
+} xXDGASelectInputReq;
+#define sz_xXDGASelectInputReq 12
+
+typedef struct _XDGAFillRectangle {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD16 x B16;
+ CARD16 y B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD32 color B32;
+} xXDGAFillRectangleReq;
+#define sz_xXDGAFillRectangleReq 20
+
+
+typedef struct _XDGACopyArea {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD16 srcx B16;
+ CARD16 srcy B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD16 dstx B16;
+ CARD16 dsty B16;
+} xXDGACopyAreaReq;
+#define sz_xXDGACopyAreaReq 20
+
+typedef struct _XDGACopyTransparentArea {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD16 srcx B16;
+ CARD16 srcy B16;
+ CARD16 width B16;
+ CARD16 height B16;
+ CARD16 dstx B16;
+ CARD16 dsty B16;
+ CARD32 key B32;
+} xXDGACopyTransparentAreaReq;
+#define sz_xXDGACopyTransparentAreaReq 24
+
+
+typedef struct _XDGAGetViewportStatus {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXDGAGetViewportStatusReq;
+#define sz_xXDGAGetViewportStatusReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 status B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXDGAGetViewportStatusReply;
+#define sz_xXDGAGetViewportStatusReply 32
+
+typedef struct _XDGASync {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+} xXDGASyncReq;
+#define sz_xXDGASyncReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+} xXDGASyncReply;
+#define sz_xXDGASyncReply 32
+
+typedef struct _XDGASetClientVersion {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD16 major B16;
+ CARD16 minor B16;
+} xXDGASetClientVersionReq;
+#define sz_xXDGASetClientVersionReq 8
+
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD16 x B16;
+ CARD16 y B16;
+ CARD32 flags B32;
+} xXDGAChangePixmapModeReq;
+#define sz_xXDGAChangePixmapModeReq 16
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 x B16;
+ CARD16 y B16;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+ CARD32 pad7 B32;
+} xXDGAChangePixmapModeReply;
+#define sz_xXDGAChangePixmapModeReply 32
+
+typedef struct _XDGACreateColormap {
+ CARD8 reqType;
+ CARD8 dgaReqType;
+ CARD16 length B16;
+ CARD32 screen B32;
+ CARD32 id B32;
+ CARD32 mode B32;
+ CARD8 alloc;
+ CARD8 pad1;
+ CARD16 pad2;
+} xXDGACreateColormapReq;
+#define sz_xXDGACreateColormapReq 20
+
+
+typedef struct {
+ union {
+ struct {
+ BYTE type;
+ BYTE detail;
+ CARD16 sequenceNumber B16;
+ } u;
+ struct {
+ CARD32 pad0 B32;
+ CARD32 time B32;
+ INT16 dx B16;
+ INT16 dy B16;
+ INT16 screen B16;
+ CARD16 state B16;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ } event;
+ } u;
+} dgaEvent;
+
+
+#endif /* _XF86DGASTR_H_ */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmode.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmode.h
new file mode 100644
index 0000000..eb56c0e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmode.h
@@ -0,0 +1,314 @@
+/* $XFree86: xc/include/extensions/xf86vmode.h,v 3.30 2001/05/07 20:09:50 mvojkovi Exp $ */
+/*
+
+Copyright 1995 Kaleb S. KEITHLEY
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
+OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY
+
+*/
+/* $Xorg: xf86vmode.h,v 1.3 2000/08/18 04:05:46 coskrey Exp $ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+#ifndef _XF86VIDMODE_H_
+#define _XF86VIDMODE_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include "SDL_name.h"
+
+#define X_XF86VidModeQueryVersion 0
+#define X_XF86VidModeGetModeLine 1
+#define X_XF86VidModeModModeLine 2
+#define X_XF86VidModeSwitchMode 3
+#define X_XF86VidModeGetMonitor 4
+#define X_XF86VidModeLockModeSwitch 5
+#define X_XF86VidModeGetAllModeLines 6
+#define X_XF86VidModeAddModeLine 7
+#define X_XF86VidModeDeleteModeLine 8
+#define X_XF86VidModeValidateModeLine 9
+#define X_XF86VidModeSwitchToMode 10
+#define X_XF86VidModeGetViewPort 11
+#define X_XF86VidModeSetViewPort 12
+/* new for version 2.x of this extension */
+#define X_XF86VidModeGetDotClocks 13
+#define X_XF86VidModeSetClientVersion 14
+#define X_XF86VidModeSetGamma 15
+#define X_XF86VidModeGetGamma 16
+#define X_XF86VidModeGetGammaRamp 17
+#define X_XF86VidModeSetGammaRamp 18
+#define X_XF86VidModeGetGammaRampSize 19
+
+#define CLKFLAG_PROGRAMABLE 1
+
+#ifdef XF86VIDMODE_EVENTS
+#define XF86VidModeNotify 0
+#define XF86VidModeNumberEvents (XF86VidModeNotify + 1)
+
+#define XF86VidModeNotifyMask 0x00000001
+
+#define XF86VidModeNonEvent 0
+#define XF86VidModeModeChange 1
+#else
+#define XF86VidModeNumberEvents 0
+#endif
+
+#define XF86VidModeBadClock 0
+#define XF86VidModeBadHTimings 1
+#define XF86VidModeBadVTimings 2
+#define XF86VidModeModeUnsuitable 3
+#define XF86VidModeExtensionDisabled 4
+#define XF86VidModeClientNotLocal 5
+#define XF86VidModeZoomLocked 6
+#define XF86VidModeNumberErrors (XF86VidModeZoomLocked + 1)
+
+#ifndef _XF86VIDMODE_SERVER_
+
+typedef struct {
+ unsigned short hdisplay;
+ unsigned short hsyncstart;
+ unsigned short hsyncend;
+ unsigned short htotal;
+ unsigned short hskew;
+ unsigned short vdisplay;
+ unsigned short vsyncstart;
+ unsigned short vsyncend;
+ unsigned short vtotal;
+ unsigned int flags;
+ int privsize;
+#if defined(__cplusplus) || defined(c_plusplus)
+ /* private is a C++ reserved word */
+ INT32 *c_private;
+#else
+ INT32 *private;
+#endif
+} SDL_NAME(XF86VidModeModeLine);
+
+typedef struct {
+ unsigned int dotclock;
+ unsigned short hdisplay;
+ unsigned short hsyncstart;
+ unsigned short hsyncend;
+ unsigned short htotal;
+ unsigned short hskew;
+ unsigned short vdisplay;
+ unsigned short vsyncstart;
+ unsigned short vsyncend;
+ unsigned short vtotal;
+ unsigned int flags;
+ int privsize;
+#if defined(__cplusplus) || defined(c_plusplus)
+ /* private is a C++ reserved word */
+ INT32 *c_private;
+#else
+ INT32 *private;
+#endif
+} SDL_NAME(XF86VidModeModeInfo);
+
+typedef struct {
+ float hi;
+ float lo;
+} SDL_NAME(XF86VidModeSyncRange);
+
+typedef struct {
+ char* vendor;
+ char* model;
+ float EMPTY;
+ unsigned char nhsync;
+ SDL_NAME(XF86VidModeSyncRange)* hsync;
+ unsigned char nvsync;
+ SDL_NAME(XF86VidModeSyncRange)* vsync;
+} SDL_NAME(XF86VidModeMonitor);
+
+typedef struct {
+ int type; /* of event */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent req */
+ Display *display; /* Display the event was read from */
+ Window root; /* root window of event screen */
+ int state; /* What happened */
+ int kind; /* What happened */
+ Bool forced; /* extents of new region */
+ Time time; /* event timestamp */
+} SDL_NAME(XF86VidModeNotifyEvent);
+
+typedef struct {
+ float red; /* Red Gamma value */
+ float green; /* Green Gamma value */
+ float blue; /* Blue Gamma value */
+} SDL_NAME(XF86VidModeGamma);
+
+
+#define SDL_XF86VidModeSelectNextMode(disp, scr) \
+ SDL_NAME(XF86VidModeSwitchMode)(disp, scr, 1)
+#define SDL_XF86VidModeSelectPrevMode(disp, scr) \
+ SDL_NAME(XF86VidModeSwitchMode)(disp, scr, -1)
+
+_XFUNCPROTOBEGIN
+
+Bool SDL_NAME(XF86VidModeQueryVersion)(
+ Display* /* dpy */,
+ int* /* majorVersion */,
+ int* /* minorVersion */
+);
+
+Bool SDL_NAME(XF86VidModeQueryExtension)(
+ Display* /* dpy */,
+ int* /* event_base */,
+ int* /* error_base */
+);
+
+Bool SDL_NAME(XF86VidModeSetClientVersion)(
+ Display* /* dpy */
+);
+
+Bool SDL_NAME(XF86VidModeGetModeLine)(
+ Display* /* dpy */,
+ int /* screen */,
+ int* /* dotclock */,
+ SDL_NAME(XF86VidModeModeLine)* /* modeline */
+);
+
+Bool SDL_NAME(XF86VidModeGetAllModeLines)(
+ Display* /* dpy */,
+ int /* screen */,
+ int* /* modecount */,
+ SDL_NAME(XF86VidModeModeInfo)*** /* modelinesPtr */
+);
+
+Bool SDL_NAME(XF86VidModeAddModeLine)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeModeInfo)* /* new modeline */,
+ SDL_NAME(XF86VidModeModeInfo)* /* after modeline */
+);
+
+Bool SDL_NAME(XF86VidModeDeleteModeLine)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeModeInfo)* /* modeline */
+);
+
+Bool SDL_NAME(XF86VidModeModModeLine)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeModeLine)* /* modeline */
+);
+
+Status SDL_NAME(XF86VidModeValidateModeLine)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeModeInfo)* /* modeline */
+);
+
+Bool SDL_NAME(XF86VidModeSwitchMode)(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* zoom */
+);
+
+Bool SDL_NAME(XF86VidModeSwitchToMode)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeModeInfo)* /* modeline */
+);
+
+Bool SDL_NAME(XF86VidModeLockModeSwitch)(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* lock */
+);
+
+Bool SDL_NAME(XF86VidModeGetMonitor)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeMonitor)* /* monitor */
+);
+
+Bool SDL_NAME(XF86VidModeGetViewPort)(
+ Display* /* dpy */,
+ int /* screen */,
+ int* /* x return */,
+ int* /* y return */
+);
+
+Bool SDL_NAME(XF86VidModeSetViewPort)(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* x */,
+ int /* y */
+);
+
+Bool SDL_NAME(XF86VidModeGetDotClocks)(
+ Display* /* dpy */,
+ int /* screen */,
+ int* /* flags return */,
+ int* /* number of clocks return */,
+ int* /* max dot clock return */,
+ int** /* clocks return */
+);
+
+Bool SDL_NAME(XF86VidModeGetGamma)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeGamma)* /* Gamma */
+);
+
+Bool SDL_NAME(XF86VidModeSetGamma)(
+ Display* /* dpy */,
+ int /* screen */,
+ SDL_NAME(XF86VidModeGamma)* /* Gamma */
+);
+
+Bool SDL_NAME(XF86VidModeSetGammaRamp)(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* size */,
+ unsigned short* /* red array */,
+ unsigned short* /* green array */,
+ unsigned short* /* blue array */
+);
+
+Bool SDL_NAME(XF86VidModeGetGammaRamp)(
+ Display* /* dpy */,
+ int /* screen */,
+ int /* size */,
+ unsigned short* /* red array */,
+ unsigned short* /* green array */,
+ unsigned short* /* blue array */
+);
+
+Bool SDL_NAME(XF86VidModeGetGammaRampSize)(
+ Display* /* dpy */,
+ int /* screen */,
+ int* /* size */
+);
+
+
+_XFUNCPROTOEND
+
+#endif
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmstr.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmstr.h
new file mode 100644
index 0000000..0c3078d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xf86vmstr.h
@@ -0,0 +1,546 @@
+/* $XFree86: xc/include/extensions/xf86vmstr.h,v 3.27 2001/08/01 00:44:36 tsi Exp $ */
+/*
+
+Copyright 1995 Kaleb S. KEITHLEY
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
+OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY
+
+*/
+/* $Xorg: xf86vmstr.h,v 1.3 2000/08/18 04:05:46 coskrey Exp $ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+#ifndef _XF86VIDMODESTR_H_
+#define _XF86VIDMODESTR_H_
+
+#include "xf86vmode.h"
+
+#define XF86VIDMODENAME "XFree86-VidModeExtension"
+
+#define XF86VIDMODE_MAJOR_VERSION 2 /* current version numbers */
+#define XF86VIDMODE_MINOR_VERSION 1
+/*
+ * major version 0 == uses parameter-to-wire functions in XFree86 libXxf86vm.
+ * major version 1 == uses parameter-to-wire functions hard-coded in xvidtune
+ * client.
+ * major version 2 == uses new protocol version in XFree86 4.0.
+ */
+
+typedef struct _XF86VidModeQueryVersion {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeQueryVersion */
+ CARD16 length B16;
+} xXF86VidModeQueryVersionReq;
+#define sz_xXF86VidModeQueryVersionReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 majorVersion B16; /* major version of XF86VidMode */
+ CARD16 minorVersion B16; /* minor version of XF86VidMode */
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86VidModeQueryVersionReply;
+#define sz_xXF86VidModeQueryVersionReply 32
+
+typedef struct _XF86VidModeGetModeLine {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86VidModeGetModeLineReq,
+ xXF86VidModeGetAllModeLinesReq,
+ xXF86VidModeGetMonitorReq,
+ xXF86VidModeGetViewPortReq,
+ xXF86VidModeGetDotClocksReq;
+#define sz_xXF86VidModeGetModeLineReq 8
+#define sz_xXF86VidModeGetAllModeLinesReq 8
+#define sz_xXF86VidModeGetMonitorReq 8
+#define sz_xXF86VidModeGetViewPortReq 8
+#define sz_xXF86VidModeGetDotClocksReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 hskew B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD16 pad2 B16;
+ CARD32 flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+ CARD32 reserved3 B32;
+ CARD32 privsize B32;
+} xXF86VidModeGetModeLineReply;
+#define sz_xXF86VidModeGetModeLineReply 52
+
+/* 0.x version */
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD32 flags B32;
+ CARD32 privsize B32;
+} xXF86OldVidModeGetModeLineReply;
+#define sz_xXF86OldVidModeGetModeLineReply 36
+
+typedef struct {
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD32 hskew B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD16 pad1 B16;
+ CARD32 flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+ CARD32 reserved3 B32;
+ CARD32 privsize B32;
+} xXF86VidModeModeInfo;
+
+/* 0.x version */
+typedef struct {
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD32 flags B32;
+ CARD32 privsize B32;
+} xXF86OldVidModeModeInfo;
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 modecount B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86VidModeGetAllModeLinesReply;
+#define sz_xXF86VidModeGetAllModeLinesReply 32
+
+typedef struct _XF86VidModeAddModeLine {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeAddMode */
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 hskew B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD16 pad1 B16;
+ CARD32 flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+ CARD32 reserved3 B32;
+ CARD32 privsize B32;
+ CARD32 after_dotclock B32;
+ CARD16 after_hdisplay B16;
+ CARD16 after_hsyncstart B16;
+ CARD16 after_hsyncend B16;
+ CARD16 after_htotal B16;
+ CARD16 after_hskew B16;
+ CARD16 after_vdisplay B16;
+ CARD16 after_vsyncstart B16;
+ CARD16 after_vsyncend B16;
+ CARD16 after_vtotal B16;
+ CARD16 pad2 B16;
+ CARD32 after_flags B32;
+ CARD32 reserved4 B32;
+ CARD32 reserved5 B32;
+ CARD32 reserved6 B32;
+} xXF86VidModeAddModeLineReq;
+#define sz_xXF86VidModeAddModeLineReq 92
+
+/* 0.x version */
+typedef struct _XF86OldVidModeAddModeLine {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeAddMode */
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD32 flags B32;
+ CARD32 privsize B32;
+ CARD32 after_dotclock B32;
+ CARD16 after_hdisplay B16;
+ CARD16 after_hsyncstart B16;
+ CARD16 after_hsyncend B16;
+ CARD16 after_htotal B16;
+ CARD16 after_vdisplay B16;
+ CARD16 after_vsyncstart B16;
+ CARD16 after_vsyncend B16;
+ CARD16 after_vtotal B16;
+ CARD32 after_flags B32;
+} xXF86OldVidModeAddModeLineReq;
+#define sz_xXF86OldVidModeAddModeLineReq 60
+
+typedef struct _XF86VidModeModModeLine {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeModModeLine */
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 hskew B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD16 pad1 B16;
+ CARD32 flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+ CARD32 reserved3 B32;
+ CARD32 privsize B32;
+} xXF86VidModeModModeLineReq;
+#define sz_xXF86VidModeModModeLineReq 48
+
+/* 0.x version */
+typedef struct _XF86OldVidModeModModeLine {
+ CARD8 reqType; /* always XF86OldVidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86OldVidModeModModeLine */
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD32 flags B32;
+ CARD32 privsize B32;
+} xXF86OldVidModeModModeLineReq;
+#define sz_xXF86OldVidModeModModeLineReq 32
+
+typedef struct _XF86VidModeValidateModeLine {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 hskew B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD16 pad1 B16;
+ CARD32 flags B32;
+ CARD32 reserved1 B32;
+ CARD32 reserved2 B32;
+ CARD32 reserved3 B32;
+ CARD32 privsize B32;
+} xXF86VidModeDeleteModeLineReq,
+ xXF86VidModeValidateModeLineReq,
+ xXF86VidModeSwitchToModeReq;
+#define sz_xXF86VidModeDeleteModeLineReq 52
+#define sz_xXF86VidModeValidateModeLineReq 52
+#define sz_xXF86VidModeSwitchToModeReq 52
+
+/* 0.x version */
+typedef struct _XF86OldVidModeValidateModeLine {
+ CARD8 reqType; /* always XF86OldVidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD32 screen B32; /* could be CARD16 but need the pad */
+ CARD32 dotclock B32;
+ CARD16 hdisplay B16;
+ CARD16 hsyncstart B16;
+ CARD16 hsyncend B16;
+ CARD16 htotal B16;
+ CARD16 vdisplay B16;
+ CARD16 vsyncstart B16;
+ CARD16 vsyncend B16;
+ CARD16 vtotal B16;
+ CARD32 flags B32;
+ CARD32 privsize B32;
+} xXF86OldVidModeDeleteModeLineReq,
+ xXF86OldVidModeValidateModeLineReq,
+ xXF86OldVidModeSwitchToModeReq;
+#define sz_xXF86OldVidModeDeleteModeLineReq 36
+#define sz_xXF86OldVidModeValidateModeLineReq 36
+#define sz_xXF86OldVidModeSwitchToModeReq 36
+
+typedef struct _XF86VidModeSwitchMode {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeSwitchMode */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 zoom B16;
+} xXF86VidModeSwitchModeReq;
+#define sz_xXF86VidModeSwitchModeReq 8
+
+typedef struct _XF86VidModeLockModeSwitch {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeLockModeSwitch */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 lock B16;
+} xXF86VidModeLockModeSwitchReq;
+#define sz_xXF86VidModeLockModeSwitchReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 status B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86VidModeValidateModeLineReply;
+#define sz_xXF86VidModeValidateModeLineReply 32
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD8 vendorLength;
+ CARD8 modelLength;
+ CARD8 nhsync;
+ CARD8 nvsync;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86VidModeGetMonitorReply;
+#define sz_xXF86VidModeGetMonitorReply 32
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 x B32;
+ CARD32 y B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86VidModeGetViewPortReply;
+#define sz_xXF86VidModeGetViewPortReply 32
+
+typedef struct _XF86VidModeSetViewPort {
+ CARD8 reqType; /* always VidModeReqCode */
+ CARD8 xf86vidmodeReqType; /* always X_XF86VidModeSetViewPort */
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+ CARD32 x B32;
+ CARD32 y B32;
+} xXF86VidModeSetViewPortReq;
+#define sz_xXF86VidModeSetViewPortReq 16
+
+typedef struct {
+ BYTE type;
+ BOOL pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 flags B32;
+ CARD32 clocks B32;
+ CARD32 maxclocks B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+} xXF86VidModeGetDotClocksReply;
+#define sz_xXF86VidModeGetDotClocksReply 32
+
+typedef struct _XF86VidModeSetClientVersion {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 major B16;
+ CARD16 minor B16;
+} xXF86VidModeSetClientVersionReq;
+#define sz_xXF86VidModeSetClientVersionReq 8
+
+typedef struct _XF86VidModeGetGamma {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xXF86VidModeGetGammaReq;
+#define sz_xXF86VidModeGetGammaReq 32
+
+typedef struct {
+ BYTE type;
+ BOOL pad;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 red B32;
+ CARD32 green B32;
+ CARD32 blue B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+} xXF86VidModeGetGammaReply;
+#define sz_xXF86VidModeGetGammaReply 32
+
+typedef struct _XF86VidModeSetGamma {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+ CARD32 red B32;
+ CARD32 green B32;
+ CARD32 blue B32;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+} xXF86VidModeSetGammaReq;
+#define sz_xXF86VidModeSetGammaReq 32
+
+
+typedef struct _XF86VidModeSetGammaRamp {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 size B16;
+} xXF86VidModeSetGammaRampReq;
+#define sz_xXF86VidModeSetGammaRampReq 8
+
+typedef struct _XF86VidModeGetGammaRamp {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 size B16;
+} xXF86VidModeGetGammaRampReq;
+#define sz_xXF86VidModeGetGammaRampReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 size B16;
+ CARD16 pad0 B16;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86VidModeGetGammaRampReply;
+#define sz_xXF86VidModeGetGammaRampReply 32
+
+typedef struct _XF86VidModeGetGammaRampSize {
+ CARD8 reqType; /* always XF86VidModeReqCode */
+ CARD8 xf86vidmodeReqType;
+ CARD16 length B16;
+ CARD16 screen B16;
+ CARD16 pad B16;
+} xXF86VidModeGetGammaRampSizeReq;
+#define sz_xXF86VidModeGetGammaRampSizeReq 8
+
+typedef struct {
+ BYTE type;
+ BOOL pad;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD16 size B16;
+ CARD16 pad0 B16;
+ CARD32 pad1 B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xXF86VidModeGetGammaRampSizeReply;
+#define sz_xXF86VidModeGetGammaRampSizeReply 32
+
+
+#endif /* _XF86VIDMODESTR_H_ */
+
diff --git a/distrib/sdl-1.2.15/src/video/Xext/extensions/xme.h b/distrib/sdl-1.2.15/src/video/Xext/extensions/xme.h
new file mode 100644
index 0000000..f550623
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/Xext/extensions/xme.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1993-2001 by Xi Graphics, Inc.
+ * All Rights Reserved.
+ *
+ * Please see the LICENSE file accompanying this distribution for licensing
+ * information.
+ *
+ * Please send any bug fixes and modifications to src@xig.com.
+ *
+ * $XiGId: xme.h,v 1.1.1.1 2001/11/19 19:01:10 jon Exp $
+ *
+ */
+
+
+#ifndef _XME_H_INCLUDED
+#define _XME_H_INCLUDED
+
+typedef struct {
+ short x;
+ short y;
+ unsigned short w;
+ unsigned short h;
+} XiGMiscViewInfo;
+
+typedef struct {
+ unsigned short width;
+ unsigned short height;
+ int refresh;
+} XiGMiscResolutionInfo;
+
+extern Bool XiGMiscQueryVersion(Display *dpy, int *major, int *minor);
+extern int XiGMiscQueryViews(Display *dpy, int screen,
+ XiGMiscViewInfo **pviews);
+extern int XiGMiscQueryResolutions(Display *dpy, int screen, int view,
+ int *pactive,
+ XiGMiscResolutionInfo **presolutions);
+extern void XiGMiscChangeResolution(Display *dpy, int screen, int view,
+ int width, int height, int refresh);
+
+/* SDL addition from Ryan: free memory used by xme. */
+extern void XiGMiscDestroy(void);
+
+#endif /* _XME_H_INCLUDED */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents.c b/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents.c
new file mode 100644
index 0000000..a26ab2d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents.c
@@ -0,0 +1,202 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting AA events into SDL events */
+
+#include <stdio.h>
+
+#include <aalib.h>
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_aavideo.h"
+#include "SDL_aaevents_c.h"
+
+/* The translation tables from a console scancode to a SDL keysym */
+static SDLKey keymap[401];
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
+
+
+void AA_PumpEvents(_THIS)
+{
+ int posted = 0;
+ int mouse_button, mouse_x, mouse_y;
+ int evt;
+ SDL_keysym keysym;
+
+ static int prev_button = -1, prev_x = -1, prev_y = -1;
+
+ if( ! this->screen ) /* Wait till we got the screen initialized */
+ return;
+
+ do {
+ posted = 0;
+ /* Gather events */
+
+ /* Get mouse status */
+ SDL_mutexP(AA_mutex);
+ aa_getmouse (AA_context, &mouse_x, &mouse_y, &mouse_button);
+ SDL_mutexV(AA_mutex);
+ mouse_x = mouse_x * this->screen->w / aa_scrwidth (AA_context);
+ mouse_y = mouse_y * this->screen->h / aa_scrheight (AA_context);
+
+ /* Compare against previous state and generate events */
+ if( prev_button != mouse_button ) {
+ if( mouse_button & AA_BUTTON1 ) {
+ if ( ! (prev_button & AA_BUTTON1) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 1, 0, 0);
+ }
+ } else {
+ if ( prev_button & AA_BUTTON1 ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 1, 0, 0);
+ }
+ }
+ if( mouse_button & AA_BUTTON2 ) {
+ if ( ! (prev_button & AA_BUTTON2) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 2, 0, 0);
+ }
+ } else {
+ if ( prev_button & AA_BUTTON2 ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 2, 0, 0);
+ }
+ }
+ if( mouse_button & AA_BUTTON3 ) {
+ if ( ! (prev_button & AA_BUTTON3) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 3, 0, 0);
+ }
+ } else {
+ if ( prev_button & AA_BUTTON3 ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 3, 0, 0);
+ }
+ }
+ }
+ if ( prev_x != mouse_x || prev_y != mouse_y ) {
+ posted += SDL_PrivateMouseMotion(0, 0, mouse_x, mouse_y);
+ }
+
+ prev_button = mouse_button;
+ prev_x = mouse_x; prev_y = mouse_y;
+
+ /* Get keyboard event */
+ SDL_mutexP(AA_mutex);
+ evt = aa_getevent(AA_context, 0);
+ SDL_mutexV(AA_mutex);
+ if ( (evt > AA_NONE) && (evt < AA_RELEASE) && (evt != AA_MOUSE) && (evt != AA_RESIZE) ) {
+ /* Key pressed */
+/* printf("Key pressed: %d (%c)\n", evt, evt); */
+ posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(evt, &keysym));
+ } else if ( evt >= AA_RELEASE ) {
+ /* Key released */
+ evt &= ~AA_RELEASE;
+/* printf("Key released: %d (%c)\n", evt, evt); */
+ posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(evt, &keysym));
+ }
+ } while ( posted );
+}
+
+void AA_InitOSKeymap(_THIS)
+{
+ int i;
+ static const char *std_keys = " 01234567890&#'()_-|$*+-=/\\:;.,!?<>{}[]@~%^\x9";
+ const char *std;
+
+ /* Initialize the AAlib key translation table */
+ for ( i=0; i<SDL_arraysize(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ /* Alphabet keys */
+ for ( i = 0; i<26; ++i ){
+ keymap['a' + i] = SDLK_a+i;
+ keymap['A' + i] = SDLK_a+i;
+ }
+ /* Function keys */
+ for ( i = 0; i<12; ++i ){
+ keymap[334 + i] = SDLK_F1+i;
+ }
+ /* Keys that have the same symbols and don't have to be translated */
+ for( std = std_keys; *std; std ++ ) {
+ keymap[*std] = *std;
+ }
+
+ keymap[13] = SDLK_RETURN;
+ keymap[AA_BACKSPACE] = SDLK_BACKSPACE;
+
+ keymap[369] = SDLK_LSHIFT;
+ keymap[370] = SDLK_RSHIFT;
+ keymap[371] = SDLK_LCTRL;
+ keymap[372] = SDLK_RCTRL;
+ keymap[377] = SDLK_LALT;
+ keymap[270] = SDLK_RALT;
+ keymap[271] = SDLK_NUMLOCK;
+ keymap[373] = SDLK_CAPSLOCK;
+ keymap[164] = SDLK_SCROLLOCK;
+
+ keymap[243] = SDLK_INSERT;
+ keymap[304] = SDLK_DELETE;
+ keymap[224] = SDLK_HOME;
+ keymap[231] = SDLK_END;
+ keymap[229] = SDLK_PAGEUP;
+ keymap[230] = SDLK_PAGEDOWN;
+
+ keymap[241] = SDLK_PRINT;
+ keymap[163] = SDLK_BREAK;
+
+ keymap[302] = SDLK_KP0;
+ keymap[300] = SDLK_KP1;
+ keymap[297] = SDLK_KP2;
+ keymap[299] = SDLK_KP3;
+ keymap[294] = SDLK_KP4;
+ keymap[301] = SDLK_KP5;
+ keymap[296] = SDLK_KP6;
+ keymap[293] = SDLK_KP7;
+ keymap[295] = SDLK_KP8;
+ keymap[298] = SDLK_KP9;
+
+ keymap[AA_ESC] = SDLK_ESCAPE;
+ keymap[AA_UP] = SDLK_UP;
+ keymap[AA_DOWN] = SDLK_DOWN;
+ keymap[AA_LEFT] = SDLK_LEFT;
+ keymap[AA_RIGHT] = SDLK_RIGHT;
+}
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Sanity check */
+ if ( scancode >= SDL_arraysize(keymap) )
+ scancode = AA_UNKNOWN;
+
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE ) {
+ /* Populate the unicode field with the ASCII value */
+ keysym->unicode = scancode;
+ }
+ return(keysym);
+}
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents_c.h b/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents_c.h
new file mode 100644
index 0000000..6dbc9f6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aaevents_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_aavideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void AA_initkeymaps(int fd);
+extern void AA_mousecallback(int button, int dx, int dy,
+ int u1,int u2,int u3, int u4);
+extern void AA_keyboardcallback(int scancode, int pressed);
+
+extern void AA_InitOSKeymap(_THIS);
+extern void AA_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse.c b/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse.c
new file mode 100644
index 0000000..dc784a5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse.c
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <stdio.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_aamouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse_c.h b/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse_c.h
new file mode 100644
index 0000000..6ce3d98
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aamouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_aavideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.c b/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.c
new file mode 100644
index 0000000..e6d5d3e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.c
@@ -0,0 +1,388 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* AAlib based SDL video driver implementation.
+*/
+
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+#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_aavideo.h"
+#include "SDL_aaevents_c.h"
+#include "SDL_aamouse_c.h"
+
+#include <aalib.h>
+
+/* Initialization/Query functions */
+static int AA_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void AA_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int AA_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int AA_LockHWSurface(_THIS, SDL_Surface *surface);
+static int AA_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void AA_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Cache the VideoDevice struct */
+static struct SDL_VideoDevice *local_this;
+
+/* AAlib driver bootstrap functions */
+
+static int AA_Available(void)
+{
+ return 1; /* Always available ! */
+}
+
+static void AA_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *AA_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = AA_VideoInit;
+ device->ListModes = AA_ListModes;
+ device->SetVideoMode = AA_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = AA_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = AA_VideoQuit;
+ device->AllocHWSurface = AA_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = AA_LockHWSurface;
+ device->UnlockHWSurface = AA_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = AA_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = AA_InitOSKeymap;
+ device->PumpEvents = AA_PumpEvents;
+
+ device->free = AA_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap AALIB_bootstrap = {
+ "aalib", "ASCII Art Library",
+ AA_Available, AA_CreateDevice
+};
+
+static void AA_ResizeHandler(aa_context *);
+
+int AA_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int keyboard;
+ int i;
+
+ /* Initialize all variables that we clean on shutdown */
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ SDL_modelist[i] = SDL_malloc(sizeof(SDL_Rect));
+ SDL_modelist[i]->x = SDL_modelist[i]->y = 0;
+ }
+ /* Modes sorted largest to smallest */
+ SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768;
+ SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600;
+ SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480;
+ SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400;
+ SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240;
+ SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200;
+ SDL_modelist[6] = NULL;
+
+ /* Initialize the library */
+
+ AA_mutex = SDL_CreateMutex();
+
+ aa_parseoptions (NULL, NULL, NULL, NULL);
+
+ AA_context = aa_autoinit(&aa_defparams);
+ if ( ! AA_context ) {
+ SDL_SetError("Unable to initialize AAlib");
+ return(-1);
+ }
+
+ /* Enable mouse and keyboard support */
+
+ if ( ! aa_autoinitkbd (AA_context, AA_SENDRELEASE) ) {
+ SDL_SetError("Unable to initialize AAlib keyboard");
+ return(-1);
+ }
+ if ( ! aa_autoinitmouse (AA_context, AA_SENDRELEASE) ) {
+ fprintf(stderr,"Warning: Unable to initialize AAlib mouse");
+ }
+ AA_rparams = aa_getrenderparams();
+
+ local_this = this;
+
+ aa_resizehandler(AA_context, AA_ResizeHandler);
+
+ fprintf(stderr,"Using AAlib driver: %s (%s)\n", AA_context->driver->name, AA_context->driver->shortname);
+
+ AA_in_x11 = (SDL_strcmp(AA_context->driver->shortname,"X11") == 0);
+ /* Determine the screen depth (use default 8-bit depth) */
+ vformat->BitsPerPixel = 8;
+ vformat->BytesPerPixel = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if(format->BitsPerPixel != 8)
+ return NULL;
+
+ if ( flags & SDL_FULLSCREEN ) {
+ return SDL_modelist;
+ } else {
+ return (SDL_Rect **) -1;
+ }
+}
+
+/* From aavga.c
+ AAlib does not give us the choice of the actual resolution, thus we have to simulate additional
+ resolution by scaling down manually each frame
+*/
+static void fastscale (register char *b1, register char *b2, int x1, int x2, int y1, int y2)
+{
+ register int ex, spx = 0, ddx, ddx1;
+ int ddy1, ddy, spy = 0, ey;
+ int x;
+ char *bb1 = b1;
+ if (!x1 || !x2 || !y1 || !y2)
+ return;
+ ddx = x1 + x1;
+ ddx1 = x2 + x2;
+ if (ddx1 < ddx)
+ spx = ddx / ddx1, ddx %= ddx1;
+ ddy = y1 + y1;
+ ddy1 = y2 + y2;
+ if (ddy1 < ddy)
+ spy = (ddy / ddy1) * x1, ddy %= ddy1;
+ ey = -ddy1;
+ for (; y2; y2--) {
+ ex = -ddx1;
+ for (x = x2; x; x--) {
+ *b2 = *b1;
+ b2++;
+ b1 += spx;
+ ex += ddx;
+ if (ex > 0) {
+ b1++;
+ ex -= ddx1;
+ }
+ }
+ bb1 += spy;
+ ey += ddy;
+ if (ey > 0) {
+ bb1 += x1;
+ ey -= ddy1;
+ }
+ b1 = bb1;
+ }
+}
+
+/* Various screen update functions available */
+static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ int mode;
+
+ if ( AA_buffer ) {
+ SDL_free( AA_buffer );
+ }
+
+ AA_buffer = SDL_malloc(width * height);
+ if ( ! AA_buffer ) {
+ SDL_SetError("Couldn't allocate buffer for requested mode");
+ return(NULL);
+ }
+
+/* printf("Setting mode %dx%d\n", width, height); */
+
+ SDL_memset(aa_image(AA_context), 0, aa_imgwidth(AA_context) * aa_imgheight(AA_context));
+ SDL_memset(AA_buffer, 0, width * height);
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, 8, 0, 0, 0, 0) ) {
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = SDL_FULLSCREEN;
+ AA_w = current->w = width;
+ AA_h = current->h = height;
+ current->pitch = current->w;
+ current->pixels = AA_buffer;
+
+ AA_x_ratio = ((double)aa_imgwidth(AA_context)) / ((double)width);
+ AA_y_ratio = ((double)aa_imgheight(AA_context)) / ((double)height);
+
+ /* Set the blit function */
+ this->UpdateRects = AA_DirectUpdate;
+
+ /* We're done */
+ return(current);
+}
+
+static void AA_ResizeHandler(aa_context *context)
+{
+ aa_resize(context);
+ local_this->hidden->x_ratio = ((double)aa_imgwidth(context)) / ((double)local_this->screen->w);
+ local_this->hidden->y_ratio = ((double)aa_imgheight(context)) / ((double)local_this->screen->h);
+
+ fastscale (local_this->hidden->buffer, aa_image(context), local_this->hidden->w, aa_imgwidth (context), local_this->hidden->h, aa_imgheight (context));
+ aa_renderpalette(context, local_this->hidden->palette, local_this->hidden->rparams, 0, 0, aa_scrwidth(context), aa_scrheight(context));
+ aa_flush(context);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int AA_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void AA_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int AA_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ /* TODO ? */
+ return(0);
+}
+static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* FIXME: How is this done with AAlib? */
+static int AA_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ SDL_mutexP(AA_mutex);
+ aa_flush(AA_context);
+ SDL_mutexV(AA_mutex);
+ return(0);
+}
+
+static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i;
+ SDL_Rect *rect;
+
+ fastscale (AA_buffer, aa_image(AA_context), AA_w, aa_imgwidth (AA_context), AA_h, aa_imgheight (AA_context));
+#if 1
+ aa_renderpalette(AA_context, AA_palette, AA_rparams, 0, 0, aa_scrwidth(AA_context), aa_scrheight(AA_context));
+#else
+ /* Render only the rectangles in the list */
+ printf("Update rects : ");
+ for ( i=0; i < numrects; ++i ) {
+ rect = &rects[i];
+ printf("(%d,%d-%d,%d)", rect->x, rect->y, rect->w, rect->h);
+ aa_renderpalette(AA_context, AA_palette, AA_rparams, rect->x * AA_x_ratio, rect->y * AA_y_ratio, rect->w * AA_x_ratio, rect->h * AA_y_ratio);
+ }
+ printf("\n");
+#endif
+ SDL_mutexP(AA_mutex);
+ aa_flush(AA_context);
+ SDL_mutexV(AA_mutex);
+ return;
+}
+
+int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+
+ for ( i=0; i < ncolors; i++ ) {
+ aa_setpalette(AA_palette, firstcolor + i,
+ colors[i].r>>2,
+ colors[i].g>>2,
+ colors[i].b>>2);
+ }
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void AA_VideoQuit(_THIS)
+{
+ int i;
+
+ aa_uninitkbd(AA_context);
+ aa_uninitmouse(AA_context);
+
+ /* Free video mode lists */
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ aa_close(AA_context);
+
+ SDL_DestroyMutex(AA_mutex);
+
+ this->screen->pixels = NULL;
+}
diff --git a/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.h b/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.h
new file mode 100644
index 0000000..987edc9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/aalib/SDL_aavideo.h
@@ -0,0 +1,66 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_aavideo_h
+#define _SDL_aavideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+#include <aalib.h>
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define SDL_NUMMODES 6
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ SDL_Rect *SDL_modelist[SDL_NUMMODES+1];
+ aa_context *context;
+ aa_palette palette;
+ aa_renderparams *rparams;
+ double x_ratio, y_ratio;
+ int w, h;
+ SDL_mutex *mutex;
+ int in_x11;
+ void *buffer;
+};
+
+/* Old variable names */
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define AA_context (this->hidden->context)
+#define AA_palette (this->hidden->palette)
+#define AA_rparams (this->hidden->rparams)
+#define AA_buffer (this->hidden->buffer)
+
+#define AA_x_ratio (this->hidden->x_ratio)
+#define AA_y_ratio (this->hidden->y_ratio)
+
+#define AA_mutex (this->hidden->mutex)
+#define AA_in_x11 (this->hidden->in_x11)
+#define AA_w (this->hidden->w)
+#define AA_h (this->hidden->h)
+
+#endif /* _SDL_aavideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p.S b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p.S
new file mode 100644
index 0000000..3cd1961
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p.S
@@ -0,0 +1,452 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/*
+ Chunky to planar conversion routine
+ 1 byte/pixel -> 4 or 8 bit planes
+
+ Patrice Mandin
+ Xavier Joubert
+ Mikael Kalms
+*/
+
+ .globl _SDL_Atari_C2pConvert
+ .globl _SDL_Atari_C2pConvert8
+ .globl _SDL_Atari_C2pConvert4
+ .globl _SDL_Atari_C2pConvert4_pal
+
+/* ------------ Conversion C2P, 8 bits ------------ */
+
+ .text
+_SDL_Atari_C2pConvert8:
+#if !defined(__mcoldfire__)
+ movel sp@(4),c2p_source
+ movel sp@(8),c2p_dest
+ movel sp@(12),c2p_width
+ movel sp@(16),c2p_height
+ movel sp@(20),c2p_dblligne
+ movel sp@(24),c2p_srcpitch
+ movel sp@(28),c2p_dstpitch
+
+ moveml d2-d7/a2-a6,sp@-
+
+ movel c2p_source,c2p_cursrc
+ movel c2p_dest,c2p_curdst
+ movel #0x0f0f0f0f,d4
+ movel #0x00ff00ff,d5
+ movel #0x55555555,d6
+ movew c2p_height+2,c2p_row
+ movew c2p_width+2,d0
+ andw #-8,d0
+ movew d0,c2p_rowlen
+
+SDL_Atari_C2p8_rowloop:
+
+ movel c2p_cursrc,a0
+ movel c2p_curdst,a1
+
+ movel a0,a2
+ addw c2p_rowlen,a2
+
+ movel a0@+,d0
+ movel a0@+,d1
+ movel a0@+,d2
+ movel a0@+,d3
+/*
+ d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
+ d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
+ d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
+ d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
+*/
+ movel d1,d7
+ lsrl #4,d7
+ eorl d0,d7
+ andl d4,d7
+ eorl d7,d0
+ lsll #4,d7
+ eorl d7,d1
+
+ movel d3,d7
+ lsrl #4,d7
+ eorl d2,d7
+ andl d4,d7
+ eorl d7,d2
+ lsll #4,d7
+ eorl d7,d3
+
+ movel d2,d7
+ lsrl #8,d7
+ eorl d0,d7
+ andl d5,d7
+ eorl d7,d0
+ lsll #8,d7
+ eorl d7,d2
+
+ movel d3,d7
+ lsrl #8,d7
+ eorl d1,d7
+ andl d5,d7
+ eorl d7,d1
+ lsll #8,d7
+ eorl d7,d3
+/*
+ d0 = a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4
+ d1 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
+ d2 = b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4
+ d3 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
+*/
+ bras SDL_Atari_C2p8_start
+
+SDL_Atari_C2p8_pix16:
+
+ movel a0@+,d0
+ movel a0@+,d1
+ movel a0@+,d2
+ movel a0@+,d3
+/*
+ d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
+ d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
+ d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
+ d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
+*/
+ movel d1,d7
+ lsrl #4,d7
+ movel a3,a1@+
+ eorl d0,d7
+ andl d4,d7
+ eorl d7,d0
+ lsll #4,d7
+ eorl d7,d1
+
+ movel d3,d7
+ lsrl #4,d7
+ eorl d2,d7
+ andl d4,d7
+ eorl d7,d2
+ movel a4,a1@+
+ lsll #4,d7
+ eorl d7,d3
+
+ movel d2,d7
+ lsrl #8,d7
+ eorl d0,d7
+ andl d5,d7
+ eorl d7,d0
+ movel a5,a1@+
+ lsll #8,d7
+ eorl d7,d2
+
+ movel d3,d7
+ lsrl #8,d7
+ eorl d1,d7
+ andl d5,d7
+ eorl d7,d1
+ movel a6,a1@+
+ lsll #8,d7
+ eorl d7,d3
+/*
+ d0 = a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4
+ d1 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0
+ d2 = b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4
+ d3 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0
+*/
+
+SDL_Atari_C2p8_start:
+
+ movel d2,d7
+ lsrl #1,d7
+ eorl d0,d7
+ andl d6,d7
+ eorl d7,d0
+ addl d7,d7
+ eorl d7,d2
+
+ movel d3,d7
+ lsrl #1,d7
+ eorl d1,d7
+ andl d6,d7
+ eorl d7,d1
+ addl d7,d7
+ eorl d7,d3
+/*
+ d0 = a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5
+ d1 = a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1
+ d2 = a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4
+ d3 = a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
+*/
+ movew d2,d7
+ movew d0,d2
+ swap d2
+ movew d2,d0
+ movew d7,d2
+
+ movew d3,d7
+ movew d1,d3
+ swap d3
+ movew d3,d1
+ movew d7,d3
+/*
+ d0 = a7b7a5b5e7f7e5f5 i7j7i5j5m7n7m5n5 a6b6a4b4e6f6e4f4 i6j6i4j4m6n6m4n4
+ d1 = a3b3a1b1e3f3e1f1 i3j3i1j1m3n3m1n1 a2b2a0b0e2f2e0f0 i2j2i0j0m2n2m0n0
+ d2 = c7d7c5d5g7h7g5h5 k7l7k5l5o7p7o5p5 c6d6c4d4g6h6g4h4 k6l6k4l4o6p6o4p4
+ d3 = c3d3c1d1g3h3g1h1 k3l3k1l1o3p3o1p1 c2d2c0d0g2h2g0h0 k2l2k0l0o2p2o0p0
+*/
+ movel d2,d7
+ lsrl #2,d7
+ eorl d0,d7
+ andl #0x33333333,d7
+ eorl d7,d0
+ lsll #2,d7
+ eorl d7,d2
+
+ movel d3,d7
+ lsrl #2,d7
+ eorl d1,d7
+ andl #0x33333333,d7
+ eorl d7,d1
+ lsll #2,d7
+ eorl d7,d3
+/*
+ d0 = a7b7c7d7e7f7g7h7 i7j7k7l7m7n7o7p7 a6b6c6d6e6f6g6h6 i6j6k6l6m6n6o6p6
+ d1 = a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2
+ d2 = a5b5c5d5e5f5g5h5 i5j5k5l5m5n5o5p5 a4b4c4d4e4f4g4h4 i4j4k4l4m4n4o4p4
+ d3 = a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0
+*/
+ swap d0
+ swap d1
+ swap d2
+ swap d3
+
+ movel d0,a6
+ movel d2,a5
+ movel d1,a4
+ movel d3,a3
+
+ cmpl a0,a2
+ bgt SDL_Atari_C2p8_pix16
+
+ movel a3,a1@+
+ movel a4,a1@+
+ movel a5,a1@+
+ movel a6,a1@+
+
+ /* Double the line ? */
+
+ movel c2p_srcpitch,d0
+ movel c2p_dstpitch,d1
+
+ tstl c2p_dblligne
+ beqs SDL_Atari_C2p8_nodblline
+
+ movel c2p_curdst,a0
+ movel a0,a1
+ addl d1,a1
+
+ movew c2p_width+2,d7
+ lsrw #4,d7
+ subql #1,d7
+SDL_Atari_C2p8_dblloop:
+ movel a0@+,a1@+
+ movel a0@+,a1@+
+ movel a0@+,a1@+
+ movel a0@+,a1@+
+ dbra d7,SDL_Atari_C2p8_dblloop
+
+ addl d1,c2p_curdst
+
+SDL_Atari_C2p8_nodblline:
+
+ /* Next line */
+
+ addl d0,c2p_cursrc
+ addl d1,c2p_curdst
+
+ subqw #1,c2p_row
+ bne SDL_Atari_C2p8_rowloop
+
+ moveml sp@+,d2-d7/a2-a6
+#endif
+ rts
+
+/* ------------ Conversion C2P, 4 bits ------------ */
+
+_SDL_Atari_C2pConvert4:
+#if !defined(__mcoldfire__)
+ movel sp@(4),c2p_source
+ movel sp@(8),c2p_dest
+ movel sp@(12),c2p_width
+ movel sp@(16),c2p_height
+ movel sp@(20),c2p_dblligne
+ movel sp@(24),c2p_srcpitch
+ movel sp@(28),c2p_dstpitch
+
+ moveml d2-d7/a2-a6,sp@-
+
+ movel c2p_source,a0
+ movel c2p_dest,a1
+ lea _SDL_Atari_table_c2p,a2
+ movel #0x00070001,d3
+#if defined(__mc68020__)
+ moveq #0,d0
+#endif
+
+ movel c2p_height,d7
+ subql #1,d7
+c2p4_bcly:
+ movel a0,a4 | Save start address of source
+ movel a1,a5 | Save start address of dest
+
+ | Conversion
+
+ movel c2p_width,d6
+ lsrw #4,d6
+ subql #1,d6
+c2p4_bclx:
+ | Octets 0-7
+
+ moveq #0,d1
+ moveq #7,d5
+c2p4_bcl07:
+#if defined(__mc68020__)
+ moveb a0@+,d0
+ lea a2@(0,d0:w:4),a3
+#else
+ moveq #0,d0
+ moveb a0@+,d0
+ lslw #2,d0
+ lea a2@(0,d0:w),a3
+#endif
+ lsll #1,d1
+ orl a3@,d1
+ dbra d5,c2p4_bcl07
+
+ movepl d1,a1@(0)
+ addw d3,a1
+ swap d3
+
+ | Octets 8-15
+
+ moveq #0,d1
+ moveq #7,d5
+c2p4_bcl815:
+#if defined(__mc68020__)
+ moveb a0@+,d0
+ lea a2@(0,d0:w:4),a3
+#else
+ moveq #0,d0
+ moveb a0@+,d0
+ lslw #2,d0
+ lea a2@(0,d0:w),a3
+#endif
+ lsll #1,d1
+ orl a3@,d1
+ dbra d5,c2p4_bcl815
+
+ movepl d1,a1@(0)
+ addw d3,a1
+ swap d3
+
+ dbra d6,c2p4_bclx
+
+ | Double line ?
+
+ tstl c2p_dblligne
+ beqs c2p4_nodblligne
+
+ movel a5,a6 | src line
+ movel a5,a1 | dest line
+ addl c2p_dstpitch,a1
+
+ movel c2p_width,d6
+ lsrw #3,d6
+ subql #1,d6
+c2p4_copydbl:
+ movel a6@+,a1@+
+ dbra d6,c2p4_copydbl
+
+ addl c2p_dstpitch,a5
+c2p4_nodblligne:
+
+ | Next line
+
+ movel a4,a0
+ addl c2p_srcpitch,a0
+ movel a5,a1
+ addl c2p_dstpitch,a1
+
+ dbra d7,c2p4_bcly
+
+ moveml sp@+,d2-d7/a2-a6
+#endif
+ rts
+
+/* ------------ Conversion of a light palette in 4 bits ------------ */
+
+_SDL_Atari_C2pConvert4_pal:
+#if !defined(__mcoldfire__)
+ /* a0 is a 256-word light palette */
+ movel sp@(4),a0
+
+ moveml d2-d3,sp@-
+
+ lea _SDL_Atari_table_c2p,a1
+ movew #255,d3
+c2p_pal_initbcl:
+ movew a0@+,d0
+ lsrw #4,d0
+ andw #15,d0
+
+ moveq #3,d1
+c2p_pal_initbyte:
+ btst d1,d0
+ sne d2
+ negw d2
+ moveb d2,a1@(0,d1:w)
+
+ dbra d1,c2p_pal_initbyte
+
+ addql #4,a1
+ dbra d3,c2p_pal_initbcl
+
+ moveml sp@+,d2-d3
+#endif
+ rts
+
+/* ------------ Buffers ------------ */
+
+ .bss
+
+ .even
+ .comm _SDL_Atari_C2pConvert,4
+ .comm _SDL_Atari_table_c2p,1024
+
+ .comm c2p_source,4 /* Source framebuffer */
+ .comm c2p_dest,4 /* Destination framebuffer */
+ .comm c2p_width,4 /* Width of zone to convert */
+ .comm c2p_height,4 /* Height of zone to convert */
+ .comm c2p_dblligne,4 /* Double the lines while converting ? */
+ .comm c2p_srcpitch,4 /* Source pitch */
+ .comm c2p_dstpitch,4 /* Destination pitch */
+ .comm c2p_cursrc,4 /* Current source line */
+ .comm c2p_curdst,4 /* Current destination line */
+ .comm c2p_rowlen,2 /* Line length in bytes */
+ .comm c2p_row,2 /* Current line number */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p_s.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p_s.h
new file mode 100644
index 0000000..48bdae7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataric2p_s.h
@@ -0,0 +1,75 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 _ATARI_C2P_h
+#define _ATARI_C2P_h
+
+#include "SDL_stdinc.h"
+
+/*--- Functions pointers ---*/
+
+/* Convert a chunky screen to bitplane screen */
+
+extern void (*SDL_Atari_C2pConvert)(
+ Uint8 *src, /* Source screen (one byte=one pixel) */
+ Uint8 *dest, /* Destination (4/8 bits planes) */
+ Uint32 width, /* Dimensions of screen to convert */
+ Uint32 height,
+ Uint32 dblligne, /* Double the lines when converting ? */
+ Uint32 srcpitch, /* Length of one source line in bytes */
+ Uint32 dstpitch /* Length of one destination line in bytes */
+);
+
+/*--- 8 bits functions ---*/
+
+/* Convert a chunky screen to bitplane screen */
+
+void SDL_Atari_C2pConvert8(
+ Uint8 *src, /* Source screen (one byte=one pixel) */
+ Uint8 *dest, /* Destination (8 bits planes) */
+ Uint32 width, /* Dimensions of screen to convert */
+ Uint32 height,
+ Uint32 dblligne, /* Double the lines when converting ? */
+ Uint32 srcpitch, /* Length of one source line in bytes */
+ Uint32 dstpitch /* Length of one destination line in bytes */
+);
+
+/*--- 4 bits functions ---*/
+
+/* Convert a chunky screen to bitplane screen */
+
+void SDL_Atari_C2pConvert4(
+ Uint8 *src, /* Source screen (one byte=one pixel) */
+ Uint8 *dest, /* Destination (4 bits planes) */
+ Uint32 width, /* Dimensions of screen to convert */
+ Uint32 height,
+ Uint32 dblligne, /* Double the lines when converting ? */
+ Uint32 srcpitch, /* Length of one source line in bytes */
+ Uint32 dstpitch /* Length of one destination line in bytes */
+);
+
+/* Conversion palette */
+
+void SDL_Atari_C2pConvert4_pal(Uint16 *lightpalette);
+
+#endif /* _ATARI_C2P_h */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse.c
new file mode 100644
index 0000000..0527380
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse.c
@@ -0,0 +1,159 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ MiNT /dev/mouse driver
+
+ Patrice Mandin
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "../../events/SDL_events_c.h"
+#include "SDL_ataridevmouse_c.h"
+
+/* Defines */
+
+#define DEVICE_NAME "/dev/mouse"
+
+/* Local variables */
+
+static int handle = -1;
+static int mouseb, prev_mouseb;
+
+/* Functions */
+
+int SDL_AtariDevMouse_Open(void)
+{
+ int r;
+ const char *mousedev;
+
+ /*
+ TODO: Fix the MiNT device driver, that locks mouse for other
+ applications, so this is disabled till fixed
+ */
+ return 0;
+
+ /* First, try SDL_MOUSEDEV device */
+ mousedev = SDL_getenv("SDL_MOUSEDEV");
+ if (!mousedev) {
+ handle = open(mousedev, 0);
+ }
+
+ /* Failed, try default device */
+ if (handle<0) {
+ handle = open(DEVICE_NAME, 0);
+ }
+
+ if (handle<0) {
+ handle = -1;
+ return 0;
+ }
+
+ /* Set non blocking mode */
+ r = fcntl(handle, F_GETFL, 0);
+ if (r<0) {
+ close(handle);
+ handle = -1;
+ return 0;
+ }
+
+ r |= O_NDELAY;
+
+ r = fcntl(handle, F_SETFL, r);
+ if (r<0) {
+ close(handle);
+ handle = -1;
+ return 0;
+ }
+
+ prev_mouseb = 7;
+ return 1;
+}
+
+void SDL_AtariDevMouse_Close(void)
+{
+ if (handle>0) {
+ close(handle);
+ handle = -1;
+ }
+}
+
+static int atari_GetButton(int button)
+{
+ switch(button)
+ {
+ case 0:
+ return SDL_BUTTON_RIGHT;
+ case 1:
+ return SDL_BUTTON_MIDDLE;
+ default:
+ break;
+ }
+
+ return SDL_BUTTON_LEFT;
+}
+
+void SDL_AtariDevMouse_PostMouseEvents(_THIS, SDL_bool buttonEvents)
+{
+ unsigned char buffer[3];
+ int mousex, mousey;
+
+ if (handle<0) {
+ return;
+ }
+
+ mousex = mousey = 0;
+ while (read(handle, buffer, sizeof(buffer))==sizeof(buffer)) {
+ mouseb = buffer[0] & 7;
+ mousex += (char) buffer[1];
+ mousey += (char) buffer[2];
+
+ /* Mouse button events */
+ if (buttonEvents && (mouseb != prev_mouseb)) {
+ int i;
+
+ for (i=0;i<3;i++) {
+ int curbutton, prevbutton;
+
+ curbutton = mouseb & (1<<i);
+ prevbutton = prev_mouseb & (1<<i);
+
+ if (curbutton && !prevbutton) {
+ SDL_PrivateMouseButton(SDL_RELEASED, atari_GetButton(i), 0, 0);
+ }
+ if (!curbutton && prevbutton) {
+ SDL_PrivateMouseButton(SDL_PRESSED, atari_GetButton(i), 0, 0);
+ }
+ }
+
+ prev_mouseb = mouseb;
+ }
+ }
+
+ /* Mouse motion event */
+ if (mousex || mousey) {
+ SDL_PrivateMouseMotion(0, 1, mousex, -mousey);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse_c.h
new file mode 100644
index 0000000..7cae022
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ataridevmouse_c.h
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ MiNT /dev/mouse driver
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_ATARI_DEVMOUSE_H_
+#define _SDL_ATARI_DEVMOUSE_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+extern int SDL_AtariDevMouse_Open(void);
+extern void SDL_AtariDevMouse_Close(void);
+extern void SDL_AtariDevMouse_PostMouseEvents(_THIS, SDL_bool buttonEvents);
+
+#endif /* _SDL_ATARI_DEVMOUSE_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi.S b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi.S
new file mode 100644
index 0000000..d8cbf48
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi.S
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/*
+ * Read EdDI version
+ *
+ * Patrice Mandin
+ */
+
+ .text
+
+ .globl _Atari_get_EdDI_version
+
+/*--- Vector installer ---*/
+
+_Atari_get_EdDI_version:
+ movel sp@(4),a0 /* Value of EdDI cookie */
+
+ /* Call EdDI function #0 */
+ clrw d0
+ jsr (a0)
+
+ rts
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi_s.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi_s.h
new file mode 100644
index 0000000..cd3e524
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarieddi_s.h
@@ -0,0 +1,54 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_Atari_eddi_s_h
+#define _SDL_Atari_eddi_s_h
+
+/*--- Defines ---*/
+
+/* EdDI versions */
+
+#define EDDI_10 (0x0100)
+#define EDDI_11 (0x0110)
+
+/* Screen format */
+
+enum {
+ VDI_FORMAT_UNKNOWN=-1,
+ VDI_FORMAT_INTER=0, /* Interleaved bitplanes */
+ VDI_FORMAT_VDI=1, /* VDI independent */
+ VDI_FORMAT_PACK=2 /* Packed pixels */
+};
+
+/* CLUT types */
+enum {
+ VDI_CLUT_NONE=0, /* Monochrome mode */
+ VDI_CLUT_HARDWARE, /* <256 colours mode */
+ VDI_CLUT_SOFTWARE /* True colour mode */
+};
+
+/*--- Functions ---*/
+
+unsigned long Atari_get_EdDI_version(void *function_pointer);
+
+#endif /* _SDL_Atari_eddi_s_h */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents.c
new file mode 100644
index 0000000..8831275
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents.c
@@ -0,0 +1,234 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager
+ *
+ * Patrice Mandin
+ *
+ * This routines choose what the final event manager will be
+ */
+
+#include <mint/cookie.h>
+#include <mint/osbind.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_atarikeys.h"
+#include "SDL_atarievents_c.h"
+#include "SDL_biosevents_c.h"
+#include "SDL_gemdosevents_c.h"
+#include "SDL_ikbdevents_c.h"
+
+enum {
+ MCH_ST=0,
+ MCH_STE,
+ MCH_TT,
+ MCH_F30,
+ MCH_CLONE,
+ MCH_ARANYM
+};
+
+/* The translation tables from a console scancode to a SDL keysym */
+static SDLKey keymap[ATARIBIOS_MAXKEYS];
+static char *keytab_normal;
+
+void (*Atari_ShutdownEvents)(void);
+
+static void Atari_InitializeEvents(_THIS)
+{
+ const char *envr;
+ long cookie_mch;
+
+ /* Test if we are on an Atari machine or not */
+ if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+ cookie_mch = 0;
+ }
+ cookie_mch >>= 16;
+
+ /* Default is Ikbd, the faster except for clones */
+ switch(cookie_mch) {
+ case MCH_ST:
+ case MCH_STE:
+ case MCH_TT:
+ case MCH_F30:
+ case MCH_ARANYM:
+ this->InitOSKeymap=AtariIkbd_InitOSKeymap;
+ this->PumpEvents=AtariIkbd_PumpEvents;
+ Atari_ShutdownEvents=AtariIkbd_ShutdownEvents;
+ break;
+ default:
+ this->InitOSKeymap=AtariGemdos_InitOSKeymap;
+ this->PumpEvents=AtariGemdos_PumpEvents;
+ Atari_ShutdownEvents=AtariGemdos_ShutdownEvents;
+ break;
+ }
+
+ envr = SDL_getenv("SDL_ATARI_EVENTSDRIVER");
+
+ if (!envr) {
+ return;
+ }
+
+ if (SDL_strcmp(envr, "ikbd") == 0) {
+ this->InitOSKeymap=AtariIkbd_InitOSKeymap;
+ this->PumpEvents=AtariIkbd_PumpEvents;
+ Atari_ShutdownEvents=AtariIkbd_ShutdownEvents;
+ }
+
+ if (SDL_strcmp(envr, "gemdos") == 0) {
+ this->InitOSKeymap=AtariGemdos_InitOSKeymap;
+ this->PumpEvents=AtariGemdos_PumpEvents;
+ Atari_ShutdownEvents=AtariGemdos_ShutdownEvents;
+ }
+
+ if (SDL_strcmp(envr, "bios") == 0) {
+ this->InitOSKeymap=AtariBios_InitOSKeymap;
+ this->PumpEvents=AtariBios_PumpEvents;
+ Atari_ShutdownEvents=AtariBios_ShutdownEvents;
+ }
+}
+
+void Atari_InitOSKeymap(_THIS)
+{
+ Atari_InitializeEvents(this);
+
+ SDL_Atari_InitInternalKeymap(this);
+
+ /* Call choosen routine */
+ this->InitOSKeymap(this);
+}
+
+void SDL_Atari_InitInternalKeymap(_THIS)
+{
+ int i;
+ _KEYTAB *key_tables;
+
+ /* Read system tables for scancode -> ascii translation */
+ key_tables = (_KEYTAB *) Keytbl(KT_NOCHANGE, KT_NOCHANGE, KT_NOCHANGE);
+ keytab_normal = key_tables->unshift;
+
+ /* Initialize keymap */
+ for ( i=0; i<ATARIBIOS_MAXKEYS; i++ )
+ keymap[i] = SDLK_UNKNOWN;
+
+ /* Functions keys */
+ for ( i = 0; i<10; i++ )
+ keymap[SCANCODE_F1 + i] = SDLK_F1+i;
+
+ /* Cursor keypad */
+ keymap[SCANCODE_HELP] = SDLK_HELP;
+ keymap[SCANCODE_UNDO] = SDLK_UNDO;
+ keymap[SCANCODE_INSERT] = SDLK_INSERT;
+ keymap[SCANCODE_CLRHOME] = SDLK_HOME;
+ keymap[SCANCODE_UP] = SDLK_UP;
+ keymap[SCANCODE_DOWN] = SDLK_DOWN;
+ keymap[SCANCODE_RIGHT] = SDLK_RIGHT;
+ keymap[SCANCODE_LEFT] = SDLK_LEFT;
+
+ /* Special keys */
+ keymap[SCANCODE_ESCAPE] = SDLK_ESCAPE;
+ keymap[SCANCODE_BACKSPACE] = SDLK_BACKSPACE;
+ keymap[SCANCODE_TAB] = SDLK_TAB;
+ keymap[SCANCODE_ENTER] = SDLK_RETURN;
+ keymap[SCANCODE_DELETE] = SDLK_DELETE;
+ keymap[SCANCODE_LEFTCONTROL] = SDLK_LCTRL;
+ keymap[SCANCODE_LEFTSHIFT] = SDLK_LSHIFT;
+ keymap[SCANCODE_RIGHTSHIFT] = SDLK_RSHIFT;
+ keymap[SCANCODE_LEFTALT] = SDLK_LALT;
+ keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK;
+}
+
+void Atari_PumpEvents(_THIS)
+{
+ Atari_InitializeEvents(this);
+
+ /* Call choosen routine */
+ this->PumpEvents(this);
+}
+
+/* Atari to Unicode charset translation table */
+
+Uint16 SDL_AtariToUnicodeTable[256]={
+ /* Standard ASCII characters from 0x00 to 0x7e */
+ /* Unicode stuff from 0x7f to 0xff */
+
+ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
+
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x0394,
+
+ 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7,
+ 0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5,
+ 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9,
+ 0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x00DF,0x0192,
+ 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA,
+ 0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB,
+ 0x00C3,0x00F5,0x00D8,0x00F8,0x0153,0x0152,0x00C0,0x00C3,
+ 0x00D5,0x00A8,0x00B4,0x2020,0x00B6,0x00A9,0x00AE,0x2122,
+
+ 0x0133,0x0132,0x05D0,0x05D1,0x05D2,0x05D3,0x05D4,0x05D5,
+ 0x05D6,0x05D7,0x05D8,0x05D9,0x05DB,0x05DC,0x05DE,0x05E0,
+ 0x05E1,0x05E2,0x05E4,0x05E6,0x05E7,0x05E8,0x05E9,0x05EA,
+ 0x05DF,0x05DA,0x05DD,0x05E3,0x05E5,0x00A7,0x2038,0x221E,
+ 0x03B1,0x03B2,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,
+ 0x03A6,0x0398,0x03A9,0x03B4,0x222E,0x03C6,0x2208,0x2229,
+ 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,
+ 0x00B0,0x2022,0x00B7,0x221A,0x207F,0x00B2,0x00B3,0x00AF
+};
+
+SDL_keysym *SDL_Atari_TranslateKey(int scancode, SDL_keysym *keysym,
+ SDL_bool pressed)
+{
+ int asciicode = 0;
+
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->mod = KMOD_NONE;
+ keysym->sym = keymap[scancode];
+ keysym->unicode = 0;
+
+ if (keysym->sym == SDLK_UNKNOWN) {
+ keysym->sym = asciicode = keytab_normal[scancode];
+ }
+
+ if (SDL_TranslateUNICODE && pressed) {
+ keysym->unicode = SDL_AtariToUnicodeTable[asciicode];
+ }
+
+ return(keysym);
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents_c.h
new file mode 100644
index 0000000..a7dd882
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarievents_c.h
@@ -0,0 +1,52 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_EVENTS_H_
+#define _SDL_ATARI_EVENTS_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define ATARIBIOS_MAXKEYS 128
+
+extern void (*Atari_ShutdownEvents)(void);
+
+extern void Atari_InitOSKeymap(_THIS);
+extern void Atari_PumpEvents(_THIS);
+
+extern void SDL_Atari_InitInternalKeymap(_THIS);
+
+/* Atari to Unicode charset translation table */
+extern Uint16 SDL_AtariToUnicodeTable[256];
+SDL_keysym *SDL_Atari_TranslateKey(int scancode, SDL_keysym *keysym,
+ SDL_bool pressed);
+
+#endif /* _SDL_ATARI_EVENTS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl.c
new file mode 100644
index 0000000..1cf2689
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl.c
@@ -0,0 +1,1086 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Atari OSMesa.ldg implementation of SDL OpenGL support */
+
+/*--- Includes ---*/
+
+#if SDL_VIDEO_OPENGL
+#include <GL/osmesa.h>
+#endif
+
+#include <mint/osbind.h>
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "SDL_atarigl_c.h"
+#if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
+#include "SDL_loadso.h"
+#endif
+
+/*--- Defines ---*/
+
+#define PATH_OSMESA_LDG "osmesa.ldg"
+#define PATH_MESAGL_LDG "mesa_gl.ldg"
+#define PATH_TINYGL_LDG "tiny_gl.ldg"
+
+#define VDI_RGB 0xf
+
+/*--- Functions prototypes ---*/
+
+#if SDL_VIDEO_OPENGL
+static void SDL_AtariGL_UnloadLibrary(_THIS);
+
+static void CopyShadowNull(_THIS, SDL_Surface *surface);
+static void CopyShadowDirect(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
+
+static void ConvertNull(_THIS, SDL_Surface *surface);
+static void Convert565To555be(_THIS, SDL_Surface *surface);
+static void Convert565To555le(_THIS, SDL_Surface *surface);
+static void Convert565le(_THIS, SDL_Surface *surface);
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
+
+static int InitNew(_THIS, SDL_Surface *current);
+static int InitOld(_THIS, SDL_Surface *current);
+#endif
+
+/*--- Public functions ---*/
+
+int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
+{
+#if SDL_VIDEO_OPENGL
+ if (gl_oldmesa) {
+ gl_active = InitOld(this, current);
+ } else {
+ gl_active = InitNew(this, current);
+ }
+#endif
+
+ return (gl_active);
+}
+
+void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
+{
+#if SDL_VIDEO_OPENGL
+ if (gl_oldmesa) {
+ /* Old mesa implementations */
+ if (this->gl_data->OSMesaDestroyLDG) {
+ this->gl_data->OSMesaDestroyLDG();
+ }
+ if (gl_shadow) {
+ Mfree(gl_shadow);
+ gl_shadow = NULL;
+ }
+ } else {
+ /* New mesa implementation */
+ if (gl_ctx) {
+ if (this->gl_data->OSMesaDestroyContext) {
+ this->gl_data->OSMesaDestroyContext(gl_ctx);
+ }
+ gl_ctx = NULL;
+ }
+ }
+
+ if (unload) {
+ SDL_AtariGL_UnloadLibrary(this);
+ }
+
+#endif /* SDL_VIDEO_OPENGL */
+ gl_active = 0;
+}
+
+int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
+{
+#if SDL_VIDEO_OPENGL
+
+#if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
+ void *handle;
+ SDL_bool cancel_load;
+
+ if (gl_active) {
+ SDL_SetError("OpenGL context already created");
+ return -1;
+ }
+
+ /* Unload previous driver */
+ SDL_AtariGL_UnloadLibrary(this);
+
+ /* Load library given by path */
+ handle = SDL_LoadObject(path);
+ if (handle == NULL) {
+ /* Try to load another one */
+ path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
+ if ( path != NULL ) {
+ handle = SDL_LoadObject(path);
+ }
+
+ /* If it does not work, try some other */
+ if (handle == NULL) {
+ path = PATH_OSMESA_LDG;
+ handle = SDL_LoadObject(path);
+ }
+
+ if (handle == NULL) {
+ path = PATH_MESAGL_LDG;
+ handle = SDL_LoadObject(path);
+ }
+
+ if (handle == NULL) {
+ path = PATH_TINYGL_LDG;
+ handle = SDL_LoadObject(path);
+ }
+ }
+
+ if (handle == NULL) {
+ SDL_SetError("Could not load OpenGL library");
+ return -1;
+ }
+
+ this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
+ this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
+ this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
+
+ cancel_load = SDL_FALSE;
+ if (this->gl_data->glGetIntegerv == NULL) {
+ cancel_load = SDL_TRUE;
+ } else {
+ /* We need either glFinish (OSMesa) or glFlush (TinyGL) */
+ if ((this->gl_data->glFinish == NULL) &&
+ (this->gl_data->glFlush == NULL)) {
+ cancel_load = SDL_TRUE;
+ }
+ }
+ if (cancel_load) {
+ SDL_SetError("Could not retrieve OpenGL functions");
+ SDL_UnloadObject(handle);
+ /* Restore pointers to static library */
+ SDL_AtariGL_InitPointers(this);
+ return -1;
+ }
+
+ /* Load functions pointers (osmesa.ldg) */
+ this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
+ this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
+ this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
+ this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
+ this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
+
+ /* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
+ this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
+ this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
+
+ gl_oldmesa = 0;
+
+ if ( (this->gl_data->OSMesaCreateContextExt == NULL) ||
+ (this->gl_data->OSMesaDestroyContext == NULL) ||
+ (this->gl_data->OSMesaMakeCurrent == NULL) ||
+ (this->gl_data->OSMesaPixelStore == NULL) ||
+ (this->gl_data->OSMesaGetProcAddress == NULL)) {
+ /* Hum, maybe old library ? */
+ if ( (this->gl_data->OSMesaCreateLDG == NULL) ||
+ (this->gl_data->OSMesaDestroyLDG == NULL)) {
+ SDL_SetError("Could not retrieve OSMesa functions");
+ SDL_UnloadObject(handle);
+ /* Restore pointers to static library */
+ SDL_AtariGL_InitPointers(this);
+ return -1;
+ } else {
+ gl_oldmesa = 1;
+ }
+ }
+
+ this->gl_config.dll_handle = handle;
+ if ( path ) {
+ SDL_strlcpy(this->gl_config.driver_path, path,
+ SDL_arraysize(this->gl_config.driver_path));
+ } else {
+ *this->gl_config.driver_path = '\0';
+ }
+
+#endif
+ this->gl_config.driver_loaded = 1;
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
+{
+ void *func = NULL;
+#if SDL_VIDEO_OPENGL
+
+ if (this->gl_config.dll_handle) {
+ func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
+ } else if (this->gl_data->OSMesaGetProcAddress) {
+ func = this->gl_data->OSMesaGetProcAddress(proc);
+ }
+
+#endif
+ return func;
+}
+
+int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+#if SDL_VIDEO_OPENGL
+ GLenum mesa_attrib;
+ SDL_Surface *surface;
+
+ if (!gl_active) {
+ return -1;
+ }
+
+ switch(attrib) {
+ case SDL_GL_RED_SIZE:
+ mesa_attrib = GL_RED_BITS;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ mesa_attrib = GL_GREEN_BITS;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ mesa_attrib = GL_BLUE_BITS;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ mesa_attrib = GL_ALPHA_BITS;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ surface = this->screen;
+ *value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
+ return 0;
+ case SDL_GL_DEPTH_SIZE:
+ mesa_attrib = GL_DEPTH_BITS;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ mesa_attrib = GL_STENCIL_BITS;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ mesa_attrib = GL_ACCUM_RED_BITS;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ mesa_attrib = GL_ACCUM_GREEN_BITS;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ mesa_attrib = GL_ACCUM_BLUE_BITS;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ mesa_attrib = GL_ACCUM_ALPHA_BITS;
+ break;
+ default :
+ return -1;
+ }
+
+ this->gl_data->glGetIntegerv(mesa_attrib, value);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+int SDL_AtariGL_MakeCurrent(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ SDL_Surface *surface;
+ GLenum type;
+
+ if (gl_oldmesa && gl_active) {
+ return 0;
+ }
+
+ if (this->gl_config.dll_handle) {
+ if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
+ (this->gl_data->OSMesaPixelStore == NULL)) {
+ return -1;
+ }
+ }
+
+ if (!gl_active) {
+ SDL_SetError("Invalid OpenGL context");
+ return -1;
+ }
+
+ surface = this->screen;
+
+ if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
+ type = GL_UNSIGNED_SHORT_5_6_5;
+ } else {
+ type = GL_UNSIGNED_BYTE;
+ }
+
+ if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
+ SDL_SetError("Can not make OpenGL context current");
+ return -1;
+ }
+
+ /* OSMesa draws upside down */
+ this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+void SDL_AtariGL_SwapBuffers(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ if (gl_active) {
+ if (this->gl_config.dll_handle) {
+ if (this->gl_data->glFinish) {
+ this->gl_data->glFinish();
+ } else if (this->gl_data->glFlush) {
+ this->gl_data->glFlush();
+ }
+ } else {
+ this->gl_data->glFinish();
+ }
+ gl_copyshadow(this, this->screen);
+ gl_convert(this, this->screen);
+ }
+#endif
+}
+
+void SDL_AtariGL_InitPointers(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
+ this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
+ this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
+ this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
+ this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
+
+ this->gl_data->glGetIntegerv = glGetIntegerv;
+ this->gl_data->glFinish = glFinish;
+ this->gl_data->glFlush = glFlush;
+
+ this->gl_data->OSMesaCreateLDG = NULL;
+ this->gl_data->OSMesaDestroyLDG = NULL;
+#endif
+}
+
+/*--- Private functions ---*/
+
+#if SDL_VIDEO_OPENGL
+static void SDL_AtariGL_UnloadLibrary(_THIS)
+{
+ if (this->gl_config.dll_handle) {
+ SDL_UnloadObject(this->gl_config.dll_handle);
+ this->gl_config.dll_handle = NULL;
+
+ /* Restore pointers to static library */
+ SDL_AtariGL_InitPointers(this);
+ }
+}
+
+/*--- Creation of an OpenGL context using new/old functions ---*/
+
+static int InitNew(_THIS, SDL_Surface *current)
+{
+ GLenum osmesa_format;
+ SDL_PixelFormat *pixel_format;
+ Uint32 redmask;
+ int recreatecontext;
+ GLint newaccumsize;
+
+ if (this->gl_config.dll_handle) {
+ if (this->gl_data->OSMesaCreateContextExt == NULL) {
+ return 0;
+ }
+ }
+
+ /* Init OpenGL context using OSMesa */
+ gl_convert = ConvertNull;
+ gl_copyshadow = CopyShadowNull;
+ gl_upsidedown = SDL_FALSE;
+
+ pixel_format = current->format;
+ redmask = pixel_format->Rmask;
+ switch (pixel_format->BitsPerPixel) {
+ case 15:
+ /* 1555, big and little endian, unsupported */
+ gl_pixelsize = 2;
+ osmesa_format = OSMESA_RGB_565;
+ if (redmask == 31<<10) {
+ gl_convert = Convert565To555be;
+ } else {
+ gl_convert = Convert565To555le;
+ }
+ break;
+ case 16:
+ gl_pixelsize = 2;
+ if (redmask == 31<<11) {
+ osmesa_format = OSMESA_RGB_565;
+ } else {
+ /* 565, little endian, unsupported */
+ osmesa_format = OSMESA_RGB_565;
+ gl_convert = Convert565le;
+ }
+ break;
+ case 24:
+ gl_pixelsize = 3;
+ if (redmask == 255<<16) {
+ osmesa_format = OSMESA_RGB;
+ } else {
+ osmesa_format = OSMESA_BGR;
+ }
+ break;
+ case 32:
+ gl_pixelsize = 4;
+ if (redmask == 255<<16) {
+ osmesa_format = OSMESA_ARGB;
+ } else if (redmask == 255<<8) {
+ osmesa_format = OSMESA_BGRA;
+ } else if (redmask == 255<<24) {
+ osmesa_format = OSMESA_RGBA;
+ } else {
+ /* ABGR format unsupported */
+ osmesa_format = OSMESA_BGRA;
+ gl_convert = ConvertBGRAToABGR;
+ }
+ break;
+ default:
+ gl_pixelsize = 1;
+ osmesa_format = OSMESA_COLOR_INDEX;
+ break;
+ }
+
+ /* Try to keep current context if possible */
+ newaccumsize =
+ this->gl_config.accum_red_size +
+ this->gl_config.accum_green_size +
+ this->gl_config.accum_blue_size +
+ this->gl_config.accum_alpha_size;
+ recreatecontext=1;
+ if (gl_ctx &&
+ (gl_curformat == osmesa_format) &&
+ (gl_curdepth == this->gl_config.depth_size) &&
+ (gl_curstencil == this->gl_config.stencil_size) &&
+ (gl_curaccum == newaccumsize)) {
+ recreatecontext = 0;
+ }
+ if (recreatecontext) {
+ SDL_AtariGL_Quit(this, SDL_FALSE);
+
+ gl_ctx = this->gl_data->OSMesaCreateContextExt(
+ osmesa_format, this->gl_config.depth_size,
+ this->gl_config.stencil_size, newaccumsize, NULL );
+
+ if (gl_ctx) {
+ gl_curformat = osmesa_format;
+ gl_curdepth = this->gl_config.depth_size;
+ gl_curstencil = this->gl_config.stencil_size;
+ gl_curaccum = newaccumsize;
+ } else {
+ gl_curformat = 0;
+ gl_curdepth = 0;
+ gl_curstencil = 0;
+ gl_curaccum = 0;
+ }
+ }
+
+ return (gl_ctx != NULL);
+}
+
+
+static int InitOld(_THIS, SDL_Surface *current)
+{
+ GLenum osmesa_format;
+ SDL_PixelFormat *pixel_format;
+ Uint32 redmask;
+ int recreatecontext, tinygl_present;
+
+ if (this->gl_config.dll_handle) {
+ if (this->gl_data->OSMesaCreateLDG == NULL) {
+ return 0;
+ }
+ }
+
+ /* TinyGL only supports VDI_RGB (OSMESA_RGB) */
+ tinygl_present=0;
+ if (this->gl_config.dll_handle) {
+ if (this->gl_data->glFinish == NULL) {
+ tinygl_present=1;
+ }
+ }
+
+ /* Init OpenGL context using OSMesa */
+ gl_convert = ConvertNull;
+ gl_copyshadow = CopyShadowNull;
+ gl_upsidedown = SDL_FALSE;
+
+ pixel_format = current->format;
+ redmask = pixel_format->Rmask;
+ switch (pixel_format->BitsPerPixel) {
+ case 15:
+ /* 15 bits unsupported */
+ if (tinygl_present) {
+ gl_pixelsize = 3;
+ osmesa_format = VDI_RGB;
+ if (redmask == 31<<10) {
+ gl_copyshadow = CopyShadowRGBTo555;
+ } else {
+ gl_copyshadow = CopyShadowRGBTo565;
+ gl_convert = Convert565To555le;
+ }
+ } else {
+ gl_pixelsize = 4;
+ gl_upsidedown = SDL_TRUE;
+ osmesa_format = OSMESA_ARGB;
+ if (redmask == 31<<10) {
+ gl_copyshadow = CopyShadow8888To555;
+ } else {
+ gl_copyshadow = CopyShadow8888To565;
+ gl_convert = Convert565To555le;
+ }
+ }
+ break;
+ case 16:
+ /* 16 bits unsupported */
+ if (tinygl_present) {
+ gl_pixelsize = 3;
+ osmesa_format = VDI_RGB;
+ gl_copyshadow = CopyShadowRGBTo565;
+ if (redmask != 31<<11) {
+ /* 565, little endian, unsupported */
+ gl_convert = Convert565le;
+ }
+ } else {
+ gl_pixelsize = 4;
+ gl_upsidedown = SDL_TRUE;
+ osmesa_format = OSMESA_ARGB;
+ gl_copyshadow = CopyShadow8888To565;
+ if (redmask != 31<<11) {
+ /* 565, little endian, unsupported */
+ gl_convert = Convert565le;
+ }
+ }
+ break;
+ case 24:
+ gl_pixelsize = 3;
+ if (tinygl_present) {
+ osmesa_format = VDI_RGB;
+ gl_copyshadow = CopyShadowDirect;
+ if (redmask != 255<<16) {
+ gl_copyshadow = CopyShadowRGBSwap;
+ }
+ } else {
+ gl_copyshadow = CopyShadowDirect;
+ gl_upsidedown = SDL_TRUE;
+ if (redmask == 255<<16) {
+ osmesa_format = OSMESA_RGB;
+ } else {
+ osmesa_format = OSMESA_BGR;
+ }
+ }
+ break;
+ case 32:
+ if (tinygl_present) {
+ gl_pixelsize = 3;
+ osmesa_format = VDI_RGB;
+ gl_copyshadow = CopyShadowRGBToARGB;
+ if (redmask == 255) {
+ gl_convert = CopyShadowRGBToABGR;
+ } else if (redmask == 255<<8) {
+ gl_convert = CopyShadowRGBToBGRA;
+ } else if (redmask == 255<<24) {
+ gl_convert = CopyShadowRGBToRGBA;
+ }
+ } else {
+ gl_pixelsize = 4;
+ gl_upsidedown = SDL_TRUE;
+ gl_copyshadow = CopyShadowDirect;
+ if (redmask == 255<<16) {
+ osmesa_format = OSMESA_ARGB;
+ } else if (redmask == 255<<8) {
+ osmesa_format = OSMESA_BGRA;
+ } else if (redmask == 255<<24) {
+ osmesa_format = OSMESA_RGBA;
+ } else {
+ /* ABGR format unsupported */
+ osmesa_format = OSMESA_BGRA;
+ gl_convert = ConvertBGRAToABGR;
+ }
+ }
+ break;
+ default:
+ if (tinygl_present) {
+ SDL_AtariGL_Quit(this, SDL_FALSE);
+ return 0;
+ }
+ gl_pixelsize = 1;
+ gl_copyshadow = CopyShadowDirect;
+ osmesa_format = OSMESA_COLOR_INDEX;
+ break;
+ }
+
+ /* Try to keep current context if possible */
+ recreatecontext=1;
+ if (gl_shadow &&
+ (gl_curformat == osmesa_format) &&
+ (gl_curwidth == current->w) &&
+ (gl_curheight == current->h)) {
+ recreatecontext = 0;
+ }
+ if (recreatecontext) {
+ SDL_AtariGL_Quit(this, SDL_FALSE);
+
+ gl_shadow = this->gl_data->OSMesaCreateLDG(
+ osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
+ );
+
+ if (gl_shadow) {
+ gl_curformat = osmesa_format;
+ gl_curwidth = current->w;
+ gl_curheight = current->h;
+ } else {
+ gl_curformat = 0;
+ gl_curwidth = 0;
+ gl_curheight = 0;
+ }
+ }
+
+ return (gl_shadow != NULL);
+}
+
+/*--- Conversions routines from shadow buffer to the screen ---*/
+
+static void CopyShadowNull(_THIS, SDL_Surface *surface)
+{
+}
+
+static void CopyShadowDirect(_THIS, SDL_Surface *surface)
+{
+ int y, srcpitch, dstpitch;
+ Uint8 *srcline, *dstline;
+
+ srcline = gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ SDL_memcpy(dstline, srcline, srcpitch);
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint16 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>1;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+ for (x=0; x<surface->w; x++) {
+ Uint16 dstcolor;
+
+ dstcolor = ((*srccol++)<<7) & (31<<10);
+ dstcolor |= ((*srccol++)<<2) & (31<<5);
+ dstcolor |= ((*srccol++)>>3) & 31;
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint16 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>1;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint16 dstcolor;
+
+ dstcolor = ((*srccol++)<<8) & (31<<11);
+ dstcolor |= ((*srccol++)<<3) & (63<<5);
+ dstcolor |= ((*srccol++)>>3) & 31;
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint8 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ *dstcol++ = srccol[2];
+ *dstcol++ = srccol[1];
+ *dstcol++ = srccol[0];
+ srccol += 3;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint32 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>2;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint32 dstcolor;
+
+ dstcolor = (*srccol++)<<16;
+ dstcolor |= (*srccol++)<<8;
+ dstcolor |= *srccol++;
+
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint32 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>2;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint32 dstcolor;
+
+ dstcolor = *srccol++;
+ dstcolor |= (*srccol++)<<8;
+ dstcolor |= (*srccol++)<<16;
+
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint32 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>2;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint32 dstcolor;
+
+ dstcolor = (*srccol++)<<8;
+ dstcolor |= (*srccol++)<<16;
+ dstcolor |= (*srccol++)<<24;
+
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint32 *dstline, *dstcol;
+ Uint8 *srcline, *srccol;
+
+ srcline = (Uint8 *)gl_shadow;
+ srcpitch = surface->w * gl_pixelsize;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>2;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint32 dstcolor;
+
+ dstcolor = (*srccol++)<<24;
+ dstcolor |= (*srccol++)<<16;
+ dstcolor |= (*srccol++)<<8;
+
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint16 *dstline, *dstcol;
+ Uint32 *srcline, *srccol;
+
+ srcline = (Uint32 *)gl_shadow;
+ srcpitch = (surface->w * gl_pixelsize) >>2;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>1;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+ for (x=0; x<surface->w; x++) {
+ Uint32 srccolor;
+ Uint16 dstcolor;
+
+ srccolor = *srccol++;
+ dstcolor = (srccolor>>9) & (31<<10);
+ dstcolor |= (srccolor>>6) & (31<<5);
+ dstcolor |= (srccolor>>3) & 31;
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
+{
+ int x,y, srcpitch, dstpitch;
+ Uint16 *dstline, *dstcol;
+ Uint32 *srcline, *srccol;
+
+ srcline = (Uint32 *)gl_shadow;
+ srcpitch = (surface->w * gl_pixelsize) >> 2;
+ dstline = surface->pixels;
+ dstpitch = surface->pitch >>1;
+ if (gl_upsidedown) {
+ srcline += (surface->h-1)*srcpitch;
+ srcpitch = -srcpitch;
+ }
+
+ for (y=0; y<surface->h; y++) {
+ srccol = srcline;
+ dstcol = dstline;
+
+ for (x=0; x<surface->w; x++) {
+ Uint32 srccolor;
+ Uint16 dstcolor;
+
+ srccolor = *srccol++;
+ dstcolor = (srccolor>>8) & (31<<11);
+ dstcolor |= (srccolor>>5) & (63<<5);
+ dstcolor |= (srccolor>>3) & 31;
+ *dstcol++ = dstcolor;
+ }
+
+ srcline += srcpitch;
+ dstline += dstpitch;
+ }
+}
+
+/*--- Conversions routines in the screen ---*/
+
+static void ConvertNull(_THIS, SDL_Surface *surface)
+{
+}
+
+static void Convert565To555be(_THIS, SDL_Surface *surface)
+{
+ int x,y, pitch;
+ unsigned short *line, *pixel;
+
+ line = surface->pixels;
+ pitch = surface->pitch >> 1;
+ for (y=0; y<surface->h; y++) {
+ pixel = line;
+ for (x=0; x<surface->w; x++) {
+ unsigned short color = *pixel;
+
+ *pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
+ }
+
+ line += pitch;
+ }
+}
+
+static void Convert565To555le(_THIS, SDL_Surface *surface)
+{
+ int x,y, pitch;
+ unsigned short *line, *pixel;
+
+ line = surface->pixels;
+ pitch = surface->pitch >>1;
+ for (y=0; y<surface->h; y++) {
+ pixel = line;
+ for (x=0; x<surface->w; x++) {
+ unsigned short color = *pixel;
+
+ color = (color & 0x1f)|((color>>1) & 0xffe0);
+ *pixel++ = SDL_Swap16(color);
+ }
+
+ line += pitch;
+ }
+}
+
+static void Convert565le(_THIS, SDL_Surface *surface)
+{
+ int x,y, pitch;
+ unsigned short *line, *pixel;
+
+ line = surface->pixels;
+ pitch = surface->pitch >>1;
+ for (y=0; y<surface->h; y++) {
+ pixel = line;
+ for (x=0; x<surface->w; x++) {
+ unsigned short color = *pixel;
+
+ *pixel++ = SDL_Swap16(color);
+ }
+
+ line += pitch;
+ }
+}
+
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
+{
+ int x,y, pitch;
+ unsigned long *line, *pixel;
+
+ line = surface->pixels;
+ pitch = surface->pitch >>2;
+ for (y=0; y<surface->h; y++) {
+ pixel = line;
+ for (x=0; x<surface->w; x++) {
+ unsigned long color = *pixel;
+
+ *pixel++ = (color<<24)|(color>>8);
+ }
+
+ line += pitch;
+ }
+}
+
+#endif /* SDL_VIDEO_OPENGL */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl_c.h
new file mode 100644
index 0000000..5adcf2a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarigl_c.h
@@ -0,0 +1,109 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Atari OSMesa.ldg implementation of SDL OpenGL support */
+
+#ifndef _SDL_ATARIGL_H_
+#define _SDL_ATARIGL_H_
+
+#if SDL_VIDEO_OPENGL
+#include <GL/osmesa.h>
+#endif
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+struct SDL_PrivateGLData {
+
+ int gl_active; /* to stop switching drivers while we have a valid context */
+
+ int gl_oldmesa; /* Old OpenGL support ? */
+
+ int gl_pixelsize; /* for CopyShadow functions */
+
+ SDL_bool gl_upsidedown; /* Some implementations draw upside down */
+
+ Uint8 *gl_shadow; /* Shadow buffer for old implementations */
+
+ /* for unsupported OSMesa buffer formats */
+ void (*ConvertSurface)(_THIS, SDL_Surface *surface);
+
+ /* to convert the shadow buffer to the screen format */
+ void (*CopyShadow)(_THIS, SDL_Surface *surface);
+
+#if SDL_VIDEO_OPENGL
+ OSMesaContext ctx;
+
+ /* OpenGL functions */
+ void (*glGetIntegerv)( GLenum pname, GLint *value );
+ void (*glFinish)(void);
+ void (*glFlush)(void);
+
+ /* osmesa.ldg */
+ OSMesaContext (*OSMesaCreateContextExt)( GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist);
+ void (*OSMesaDestroyContext)( OSMesaContext ctx );
+ GLboolean (*OSMesaMakeCurrent)( OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height );
+ void (*OSMesaPixelStore)( GLint pname, GLint value );
+ void * (*OSMesaGetProcAddress)( const char *funcName );
+
+ /* mesa_gl.ldg, tiny_gl.ldg */
+ void *(*OSMesaCreateLDG)( long format, long type, long width, long height );
+ void (*OSMesaDestroyLDG)(void);
+
+ /* Info needed to compare existing context with new asked one */
+ int width, height;
+ GLenum format;
+ GLint depth,stencil,accum;
+#endif
+};
+
+/* Variable names */
+#define gl_active (this->gl_data->gl_active)
+#define gl_ctx (this->gl_data->ctx)
+#define gl_oldmesa (this->gl_data->gl_oldmesa)
+#define gl_pixelsize (this->gl_data->gl_pixelsize)
+#define gl_upsidedown (this->gl_data->gl_upsidedown)
+#define gl_shadow (this->gl_data->gl_shadow)
+#define gl_convert (this->gl_data->ConvertSurface)
+#define gl_copyshadow (this->gl_data->CopyShadow)
+#define gl_curformat (this->gl_data->format)
+#define gl_curdepth (this->gl_data->depth)
+#define gl_curstencil (this->gl_data->stencil)
+#define gl_curaccum (this->gl_data->accum)
+#define gl_curwidth (this->gl_data->width)
+#define gl_curheight (this->gl_data->height)
+
+/* OpenGL functions */
+extern int SDL_AtariGL_Init(_THIS, SDL_Surface *current);
+extern void SDL_AtariGL_Quit(_THIS, SDL_bool unload);
+extern void SDL_AtariGL_InitPointers(_THIS);
+
+extern int SDL_AtariGL_LoadLibrary(_THIS, const char *path);
+extern void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc);
+extern int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+extern int SDL_AtariGL_MakeCurrent(_THIS);
+extern void SDL_AtariGL_SwapBuffers(_THIS);
+
+#endif /* _SDL_ATARIGL_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarikeys.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarikeys.h
new file mode 100644
index 0000000..a9f7cfd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarikeys.h
@@ -0,0 +1,140 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/*
+ * Atari Scancode definitions
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARIKEYS_H_
+#define _SDL_ATARIKEYS_H_
+
+/* --- Keyboard scancodes --- */
+/* taken from svgalib/vgakeyboard.h */
+
+#define SCANCODE_ESCAPE 0x01
+#define SCANCODE_1 0x02
+#define SCANCODE_2 0x03
+#define SCANCODE_3 0x04
+#define SCANCODE_4 0x05
+#define SCANCODE_5 0x06
+#define SCANCODE_6 0x07
+#define SCANCODE_7 0x08
+#define SCANCODE_8 0x09
+#define SCANCODE_9 0x0a
+#define SCANCODE_0 0x0b
+#define SCANCODE_MINUS 0x0c
+#define SCANCODE_EQUAL 0x0d
+#define SCANCODE_BACKSPACE 0x0e
+
+#define SCANCODE_TAB 0x0f
+#define SCANCODE_Q 0x10
+#define SCANCODE_W 0x11
+#define SCANCODE_E 0x12
+#define SCANCODE_R 0x13
+#define SCANCODE_T 0x14
+#define SCANCODE_Y 0x15
+#define SCANCODE_U 0x16
+#define SCANCODE_I 0x17
+#define SCANCODE_O 0x18
+#define SCANCODE_P 0x19
+#define SCANCODE_BRACKET_LEFT 0x1a
+#define SCANCODE_BRACKET_RIGHT 0x1b
+#define SCANCODE_ENTER 0x1c
+#define SCANCODE_DELETE 0x53
+
+#define SCANCODE_LEFTCONTROL 0x1d
+#define SCANCODE_A 0x1e
+#define SCANCODE_S 0x1f
+#define SCANCODE_D 0x20
+#define SCANCODE_F 0x21
+#define SCANCODE_G 0x22
+#define SCANCODE_H 0x23
+#define SCANCODE_J 0x24
+#define SCANCODE_K 0x25
+#define SCANCODE_L 0x26
+#define SCANCODE_SEMICOLON 0x27
+#define SCANCODE_APOSTROPHE 0x28
+#define SCANCODE_GRAVE 0x29
+
+#define SCANCODE_LEFTSHIFT 0x2a
+#define SCANCODE_BACKSLASH 0x2b
+#define SCANCODE_Z 0x2c
+#define SCANCODE_X 0x2d
+#define SCANCODE_C 0x2e
+#define SCANCODE_V 0x2f
+#define SCANCODE_B 0x30
+#define SCANCODE_N 0x31
+#define SCANCODE_M 0x32
+#define SCANCODE_COMMA 0x33
+#define SCANCODE_PERIOD 0x34
+#define SCANCODE_SLASH 0x35
+#define SCANCODE_RIGHTSHIFT 0x36
+
+#define SCANCODE_LEFTALT 0x38
+#define SCANCODE_SPACE 0x39
+#define SCANCODE_CAPSLOCK 0x3a
+
+/* Functions keys */
+#define SCANCODE_F1 0x3b
+#define SCANCODE_F2 0x3c
+#define SCANCODE_F3 0x3d
+#define SCANCODE_F4 0x3e
+#define SCANCODE_F5 0x3f
+#define SCANCODE_F6 0x40
+#define SCANCODE_F7 0x41
+#define SCANCODE_F8 0x42
+#define SCANCODE_F9 0x43
+#define SCANCODE_F10 0x44
+
+/* Numeric keypad */
+#define SCANCODE_KP0 0x70
+#define SCANCODE_KP1 0x6d
+#define SCANCODE_KP2 0x6e
+#define SCANCODE_KP3 0x6f
+#define SCANCODE_KP4 0x6a
+#define SCANCODE_KP5 0x6b
+#define SCANCODE_KP6 0x6c
+#define SCANCODE_KP7 0x67
+#define SCANCODE_KP8 0x68
+#define SCANCODE_KP9 0x69
+#define SCANCODE_KP_PERIOD 0x71
+#define SCANCODE_KP_DIVIDE 0x65
+#define SCANCODE_KP_MULTIPLY 0x66
+#define SCANCODE_KP_MINUS 0x4a
+#define SCANCODE_KP_PLUS 0x4e
+#define SCANCODE_KP_ENTER 0x72
+#define SCANCODE_KP_LEFTPAREN 0x63
+#define SCANCODE_KP_RIGHTPAREN 0x64
+
+/* Cursor keypad */
+#define SCANCODE_HELP 0x62
+#define SCANCODE_UNDO 0x61
+#define SCANCODE_INSERT 0x52
+#define SCANCODE_CLRHOME 0x47
+#define SCANCODE_UP 0x48
+#define SCANCODE_DOWN 0x50
+#define SCANCODE_RIGHT 0x4d
+#define SCANCODE_LEFT 0x4b
+
+#endif /* _SDL_ATARIKEYS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc.c
new file mode 100644
index 0000000..224baef
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc.c
@@ -0,0 +1,52 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Memory allocation
+ *
+ * Patrice Mandin
+ */
+
+#include <mint/osbind.h>
+
+#include "SDL_stdinc.h"
+
+/*--- Variables ---*/
+
+static int atari_mxalloc_avail=-1;
+
+/*--- Functions ---*/
+
+void *Atari_SysMalloc(Uint32 size, Uint16 alloc_type)
+{
+ /* Test if Mxalloc() available */
+ if (atari_mxalloc_avail<0) {
+ atari_mxalloc_avail = ((Sversion()&0xFF)>=0x01) | (Sversion()>=0x1900);
+ }
+
+ if (atari_mxalloc_avail) {
+ return (void *) Mxalloc(size, alloc_type);
+ } else {
+ return (void *) Malloc(size);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc_c.h
new file mode 100644
index 0000000..937408d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarimxalloc_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Memory allocation
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_MXALLOC_H_
+#define _SDL_ATARI_MXALLOC_H_
+
+/*--- Functions ---*/
+
+extern void *Atari_SysMalloc(Uint32 size, Uint16 alloc_type);
+
+#endif /* _SDL_ATARI_MXALLOC_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarisuper.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarisuper.h
new file mode 100644
index 0000000..8f25c7e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_atarisuper.h
@@ -0,0 +1,61 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 _ATARI_SUPER_h
+#define _ATARI_SUPER_h
+
+#include "SDL_stdinc.h"
+
+#ifndef SuperToUser
+
+/*
+ * Safe binding to switch back from supervisor to user mode.
+ * On TOS or EmuTOS, if the stack pointer has changed between Super(0)
+ * and Super(oldssp), the resulting user stack pointer is wrong.
+ * This bug does not occur with FreeMiNT.
+ * So the safe way to return from supervisor to user mode is to backup
+ * the stack pointer then restore it after the trap.
+ * Sometimes, GCC optimizes the stack usage, so this matters.
+ */
+#define SuperToUser(ptr) \
+(void)__extension__ \
+({ \
+ register long retvalue __asm__("d0"); \
+ register long sp_backup; \
+ \
+ __asm__ volatile \
+ ( \
+ "movl sp,%1\n\t" \
+ "movl %2,sp@-\n\t" \
+ "movw #0x20,sp@-\n\t" \
+ "trap #1\n\t" \
+ "movl %1,sp\n\t" \
+ : "=r"(retvalue), "=&r"(sp_backup) /* outputs */ \
+ : "g"((long)(ptr)) /* inputs */ \
+ : "d1", "d2", "a0", "a1", "a2" \
+ ); \
+})
+
+#endif /* SuperToUser */
+
+#endif /* _ATARI_SUPER_h */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents.c
new file mode 100644
index 0000000..3d36b2b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents.c
@@ -0,0 +1,131 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using BIOS
+ *
+ * Patrice Mandin
+ */
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/cookie.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_atarikeys.h"
+#include "SDL_atarievents_c.h"
+#include "SDL_xbiosevents_c.h"
+#include "SDL_ataridevmouse_c.h"
+
+static unsigned char bios_currentkeyboard[ATARIBIOS_MAXKEYS];
+static unsigned char bios_previouskeyboard[ATARIBIOS_MAXKEYS];
+static SDL_bool use_dev_mouse = SDL_FALSE;
+
+static void UpdateSpecialKeys(int special_keys_state);
+
+void AtariBios_InitOSKeymap(_THIS)
+{
+ int vectors_mask;
+/* unsigned long dummy;*/
+
+ SDL_memset(bios_currentkeyboard, 0, sizeof(bios_currentkeyboard));
+ SDL_memset(bios_previouskeyboard, 0, sizeof(bios_previouskeyboard));
+
+ use_dev_mouse = (SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
+
+ vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS; /* XBIOS joystick events */
+ if (!use_dev_mouse) {
+ vectors_mask |= ATARI_XBIOS_MOUSEEVENTS; /* XBIOS mouse events */
+ }
+/* if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
+ vectors_mask = 0;
+ }*/
+
+ SDL_AtariXbios_InstallVectors(vectors_mask);
+}
+
+void AtariBios_PumpEvents(_THIS)
+{
+ int i;
+ SDL_keysym keysym;
+
+ /* Update pressed keys */
+ SDL_memset(bios_currentkeyboard, 0, ATARIBIOS_MAXKEYS);
+
+ while (Bconstat(_CON)) {
+ unsigned long key_pressed;
+ key_pressed=Bconin(_CON);
+ bios_currentkeyboard[(key_pressed>>16)&(ATARIBIOS_MAXKEYS-1)]=0xFF;
+ }
+
+ /* Read special keys */
+ UpdateSpecialKeys(Kbshift(-1));
+
+ /* Now generate events */
+ for (i=0; i<ATARIBIOS_MAXKEYS; i++) {
+ /* Key pressed ? */
+ if (bios_currentkeyboard[i] && !bios_previouskeyboard[i])
+ SDL_PrivateKeyboard(SDL_PRESSED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE));
+
+ /* Key unpressed ? */
+ if (bios_previouskeyboard[i] && !bios_currentkeyboard[i])
+ SDL_PrivateKeyboard(SDL_RELEASED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE));
+ }
+
+ if (use_dev_mouse) {
+ SDL_AtariDevMouse_PostMouseEvents(this, SDL_TRUE);
+ } else {
+ SDL_AtariXbios_PostMouseEvents(this, SDL_TRUE);
+ }
+
+ /* Will be previous table */
+ SDL_memcpy(bios_previouskeyboard, bios_currentkeyboard, sizeof(bios_previouskeyboard));
+}
+
+static void UpdateSpecialKeys(int special_keys_state)
+{
+#define UPDATE_SPECIAL_KEYS(numbit,scancode) \
+ { \
+ if (special_keys_state & (1<<(numbit))) { \
+ bios_currentkeyboard[scancode]=0xFF; \
+ } \
+ }
+
+ UPDATE_SPECIAL_KEYS(K_RSHIFT, SCANCODE_RIGHTSHIFT);
+ UPDATE_SPECIAL_KEYS(K_LSHIFT, SCANCODE_LEFTSHIFT);
+ UPDATE_SPECIAL_KEYS(K_CTRL, SCANCODE_LEFTCONTROL);
+ UPDATE_SPECIAL_KEYS(K_ALT, SCANCODE_LEFTALT);
+ UPDATE_SPECIAL_KEYS(K_CAPSLOCK, SCANCODE_CAPSLOCK);
+}
+
+void AtariBios_ShutdownEvents(void)
+{
+ SDL_AtariXbios_RestoreVectors();
+ if (use_dev_mouse) {
+ SDL_AtariDevMouse_Close();
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents_c.h
new file mode 100644
index 0000000..f016e6a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_biosevents_c.h
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using BIOS
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_BIOSEVENTS_H_
+#define _SDL_ATARI_BIOSEVENTS_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+extern void AtariBios_InitOSKeymap(_THIS);
+extern void AtariBios_PumpEvents(_THIS);
+extern void AtariBios_ShutdownEvents(void);
+
+#endif /* _SDL_ATARI_BIOSEVENTS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents.c
new file mode 100644
index 0000000..e1ebaa6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents.c
@@ -0,0 +1,132 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using Gemdos
+ *
+ * Patrice Mandin
+ */
+
+/* Mint includes */
+#include <mint/osbind.h>
+#include <mint/cookie.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_atarikeys.h"
+#include "SDL_atarievents_c.h"
+#include "SDL_xbiosevents_c.h"
+#include "SDL_ataridevmouse_c.h"
+
+/* To save state of keyboard */
+
+static unsigned char gemdos_currentkeyboard[ATARIBIOS_MAXKEYS];
+static unsigned char gemdos_previouskeyboard[ATARIBIOS_MAXKEYS];
+static SDL_bool use_dev_mouse = SDL_FALSE;
+
+static void UpdateSpecialKeys(int special_keys_state);
+
+void AtariGemdos_InitOSKeymap(_THIS)
+{
+ int vectors_mask;
+/* unsigned long dummy;*/
+
+ SDL_memset(gemdos_currentkeyboard, 0, sizeof(gemdos_currentkeyboard));
+ SDL_memset(gemdos_previouskeyboard, 0, sizeof(gemdos_previouskeyboard));
+
+ use_dev_mouse = (SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
+
+ vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS; /* XBIOS joystick events */
+ if (!use_dev_mouse) {
+ vectors_mask |= ATARI_XBIOS_MOUSEEVENTS; /* XBIOS mouse events */
+ }
+/* if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
+ vectors_mask = 0;
+ }*/
+ SDL_AtariXbios_InstallVectors(vectors_mask);
+}
+
+void AtariGemdos_PumpEvents(_THIS)
+{
+ int i;
+ SDL_keysym keysym;
+
+ /* Update pressed keys */
+ SDL_memset(gemdos_currentkeyboard, 0, ATARIBIOS_MAXKEYS);
+
+ while (Cconis()!=DEV_BUSY) {
+ unsigned long key_pressed;
+ key_pressed=Cnecin();
+ gemdos_currentkeyboard[(key_pressed>>16)&(ATARIBIOS_MAXKEYS-1)]=0xFF;
+ }
+
+ /* Read special keys */
+ UpdateSpecialKeys(Kbshift(-1));
+
+ /* Now generate events */
+ for (i=0; i<ATARIBIOS_MAXKEYS; i++) {
+ /* Key pressed ? */
+ if (gemdos_currentkeyboard[i] && !gemdos_previouskeyboard[i])
+ SDL_PrivateKeyboard(SDL_PRESSED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE));
+
+ /* Key unpressed ? */
+ if (gemdos_previouskeyboard[i] && !gemdos_currentkeyboard[i])
+ SDL_PrivateKeyboard(SDL_RELEASED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE));
+ }
+
+ if (use_dev_mouse) {
+ SDL_AtariDevMouse_PostMouseEvents(this, SDL_TRUE);
+ } else {
+ SDL_AtariXbios_PostMouseEvents(this, SDL_TRUE);
+ }
+
+ /* Will be previous table */
+ SDL_memcpy(gemdos_previouskeyboard, gemdos_currentkeyboard, sizeof(gemdos_previouskeyboard));
+}
+
+static void UpdateSpecialKeys(int special_keys_state)
+{
+#define UPDATE_SPECIAL_KEYS(numbit,scancode) \
+ { \
+ if (special_keys_state & (1<<(numbit))) { \
+ gemdos_currentkeyboard[scancode]=0xFF; \
+ } \
+ }
+
+ UPDATE_SPECIAL_KEYS(K_RSHIFT, SCANCODE_RIGHTSHIFT);
+ UPDATE_SPECIAL_KEYS(K_LSHIFT, SCANCODE_LEFTSHIFT);
+ UPDATE_SPECIAL_KEYS(K_CTRL, SCANCODE_LEFTCONTROL);
+ UPDATE_SPECIAL_KEYS(K_ALT, SCANCODE_LEFTALT);
+ UPDATE_SPECIAL_KEYS(K_CAPSLOCK, SCANCODE_CAPSLOCK);
+}
+
+void AtariGemdos_ShutdownEvents(void)
+{
+ SDL_AtariXbios_RestoreVectors();
+ if (use_dev_mouse) {
+ SDL_AtariDevMouse_Close();
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents_c.h
new file mode 100644
index 0000000..b9924e6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_gemdosevents_c.h
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using Gemdos
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_GEMDOSEVENTS_H_
+#define _SDL_ATARI_GEMDOSEVENTS_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+extern void AtariGemdos_InitOSKeymap(_THIS);
+extern void AtariGemdos_PumpEvents(_THIS);
+extern void AtariGemdos_ShutdownEvents(void);
+
+#endif /* _SDL_ATARI_GEMDOSEVENTS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents.c
new file mode 100644
index 0000000..35fc5cb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents.c
@@ -0,0 +1,124 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using hardware IKBD
+ *
+ * Patrice Mandin
+ */
+
+/* Mint includes */
+#include <mint/osbind.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_atarikeys.h"
+#include "SDL_atarievents_c.h"
+#include "SDL_ikbdinterrupt_s.h"
+
+#define KEY_PRESSED 0xff
+#define KEY_UNDEFINED 0x80
+#define KEY_RELEASED 0x00
+
+static Uint16 atari_prevmouseb; /* save state of mouse buttons */
+
+void AtariIkbd_InitOSKeymap(_THIS)
+{
+ SDL_memset((void *) SDL_AtariIkbd_keyboard, KEY_UNDEFINED, sizeof(SDL_AtariIkbd_keyboard));
+
+ /* Now install our handler */
+ SDL_AtariIkbd_mouseb = SDL_AtariIkbd_mousex = SDL_AtariIkbd_mousey = 0;
+ atari_prevmouseb = 0;
+
+ Supexec(SDL_AtariIkbdInstall);
+}
+
+static int atari_GetButton(int button)
+{
+ switch(button)
+ {
+ case 0:
+ return SDL_BUTTON_RIGHT;
+ break;
+ case 1:
+ default:
+ return SDL_BUTTON_LEFT;
+ break;
+ }
+}
+
+void AtariIkbd_PumpEvents(_THIS)
+{
+ int i;
+ SDL_keysym keysym;
+
+ /*--- Send keyboard events ---*/
+
+ for (i=0; i<ATARIBIOS_MAXKEYS; i++) {
+ /* Key pressed ? */
+ if (SDL_AtariIkbd_keyboard[i]==KEY_PRESSED) {
+ SDL_PrivateKeyboard(SDL_PRESSED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE));
+ SDL_AtariIkbd_keyboard[i]=KEY_UNDEFINED;
+ }
+
+ /* Key released ? */
+ if (SDL_AtariIkbd_keyboard[i]==KEY_RELEASED) {
+ SDL_PrivateKeyboard(SDL_RELEASED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE));
+ SDL_AtariIkbd_keyboard[i]=KEY_UNDEFINED;
+ }
+ }
+
+ /*--- Send mouse events ---*/
+
+ /* Mouse motion ? */
+ if (SDL_AtariIkbd_mousex || SDL_AtariIkbd_mousey) {
+ SDL_PrivateMouseMotion(0, 1, SDL_AtariIkbd_mousex, SDL_AtariIkbd_mousey);
+ SDL_AtariIkbd_mousex = SDL_AtariIkbd_mousey = 0;
+ }
+
+ /* Mouse button ? */
+ if (SDL_AtariIkbd_mouseb != atari_prevmouseb) {
+ for (i=0;i<2;i++) {
+ int curbutton, prevbutton;
+
+ curbutton = SDL_AtariIkbd_mouseb & (1<<i);
+ prevbutton = atari_prevmouseb & (1<<i);
+
+ if (curbutton && !prevbutton) {
+ SDL_PrivateMouseButton(SDL_PRESSED, atari_GetButton(i), 0, 0);
+ }
+ if (!curbutton && prevbutton) {
+ SDL_PrivateMouseButton(SDL_RELEASED, atari_GetButton(i), 0, 0);
+ }
+ }
+ atari_prevmouseb = SDL_AtariIkbd_mouseb;
+ }
+}
+
+void AtariIkbd_ShutdownEvents(void)
+{
+ Supexec(SDL_AtariIkbdUninstall);
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents_c.h
new file mode 100644
index 0000000..753e777
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdevents_c.h
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Atari keyboard events manager, using hardware IKBD
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_IKBDEVENTS_H_
+#define _SDL_ATARI_IKBDEVENTS_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+extern void AtariIkbd_InitOSKeymap(_THIS);
+extern void AtariIkbd_PumpEvents(_THIS);
+extern void AtariIkbd_ShutdownEvents(void);
+
+#endif /* _SDL_ATARI_IKBDEVENTS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt.S b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt.S
new file mode 100644
index 0000000..21facc8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt.S
@@ -0,0 +1,404 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/*
+ * IKBD 6301 interrupt routine
+ *
+ * Patrice Mandin
+ */
+
+ .text
+
+ .globl _SDL_AtariIkbdInstall
+ .globl _SDL_AtariIkbdUninstall
+
+ .globl _SDL_AtariIkbd_keyboard
+ .globl _SDL_AtariIkbd_mouseb
+ .globl _SDL_AtariIkbd_mousex
+ .globl _SDL_AtariIkbd_mousey
+ .globl _SDL_AtariIkbd_joystick
+
+ .globl _SDL_AtariIkbd_enabled
+
+/*--- Install our IKBD vector ---*/
+
+_SDL_AtariIkbdInstall:
+#if defined(__mcoldfire__)
+ lea sp@(-16),sp
+ moveml d0-d1/a0-a1,sp@
+#else
+ moveml d0-d1/a0-a1,sp@-
+#endif
+
+ | Disable interrupts
+
+ movew #0x2700,sr
+
+ | Save MFP registers used for keyboard
+
+ lea 0xfffffa00:w,a0
+ btst #6,a0@(0x09)
+#if defined(__mcoldfire__)
+ sne d0
+ move.b d0,ikbd_ierb
+#else
+ sne ikbd_ierb
+#endif
+ btst #6,a0@(0x15)
+#if defined(__mcoldfire__)
+ sne d0
+ move.b d0,ikbd_imrb
+#else
+ sne ikbd_imrb
+#endif
+
+ | Set our routine
+
+#if defined(__mcoldfire__)
+ movel 0x118:w,d0
+ movel d0,old_ikbd
+ lea ikbd,a0
+ movel a0,0x118:w
+ moveql #6,d0
+ bset d0,0xfffffa09:w | IERB
+ bset d0,0xfffffa15:w | IMRB
+#else
+ movel 0x118:w,old_ikbd
+ movel #ikbd,0x118:w
+ bset #6,0xfffffa09:w | IERB
+ bset #6,0xfffffa15:w | IMRB
+#endif
+
+ | Set mouse relative mode
+
+#if defined(__mcoldfire__)
+ moveql #8,d0
+ moveb d0,0xfffffc02:w
+#else
+ moveb #8,0xfffffc02:w
+#endif
+
+ | Reenable interrupts
+
+ movew #0x2300,sr
+
+ | Interrupts done
+
+#if defined(__mcoldfire__)
+ movel #0xffff,d0
+ movew d0,_SDL_AtariIkbd_enabled
+
+ moveml sp@,d0-d1/a0-a1
+ lea sp@(16),sp
+#else
+ movew #0xffff,_SDL_AtariIkbd_enabled
+
+ moveml sp@+,d0-d1/a0-a1
+#endif
+ rts
+
+/*--- Uninstall our IKBD vector ---*/
+
+_SDL_AtariIkbdUninstall:
+ movel a0,sp@-
+
+ | Disable interrupts
+
+ movew #0x2700,sr
+
+ | Restore previous MFP registers
+
+ lea 0xfffffa00:w,a0
+
+ bclr #6,a0@(0x09)
+ tstb ikbd_ierb
+ beqs ikbd_restoreierb
+ bset #6,a0@(0x09)
+ikbd_restoreierb:
+
+ bclr #6,a0@(0x15)
+ tstb ikbd_imrb
+ beqs ikbd_restoreimrb
+ bset #6,a0@(0x15)
+ikbd_restoreimrb:
+
+#if defined(__mcoldfire__)
+ movel old_ikbd,a0
+ movel a0,0x118:w
+#else
+ movel old_ikbd,0x118:w
+#endif
+
+ | Clear keyboard buffer
+
+ lea 0xfffffc00:w,a0
+ikbd_videbuffer:
+ btst #0,a0@
+ beqs ikbd_finbuffer
+ tstb a0@(0x02)
+ bras ikbd_videbuffer
+ikbd_finbuffer:
+
+ | Reenable interrupts
+
+ movew #0x2300,sr
+
+ movel sp@+,a0
+ rts
+
+ .bss
+
+ .even
+ .comm ikbd_ierb,1
+ .comm ikbd_imrb,1
+
+/*--- Our custom IKBD vector ---*/
+
+ .text
+ .even
+ .ascii "XBRA"
+ .ascii "LSDL"
+ .comm old_ikbd,4*1
+ikbd:
+#if defined(__mcoldfire__)
+ lea sp@(-12),sp
+ moveml d0-d1/a0,sp@
+#else
+ moveml d0-d1/a0,sp@-
+#endif
+
+ | Check if source is IKBD or MIDI
+#if defined(__mcoldfire__)
+ moveql #0,d0
+ btst d0,0xfffffc00.w
+#else
+ btst #0,0xfffffc00.w
+#endif
+ beqs ikbd_oldmidi
+
+ moveb 0xfffffc02:w,d0
+
+ | Joystick packet ?
+
+ cmpb #0xff,d0
+ beqs ikbd_yes_joystick
+
+ | Mouse packet ?
+
+ cmpb #0xf8,d0
+ bmis ikbd_no_mouse
+ cmpb #0xfc,d0
+ bpls ikbd_no_mouse
+
+ | Mouse packet, byte #1
+
+ikbd_yes_mouse:
+#if defined(__mcoldfire__)
+ andl #3,d0
+#else
+ andw #3,d0
+#endif
+ movew d0,_SDL_AtariIkbd_mouseb
+
+#if defined(__mcoldfire__)
+ movel #ikbd_mousex,d0
+ movel d0,0x118:w
+#else
+ movel #ikbd_mousex,0x118:w
+#endif
+ bras ikbd_endit_stack
+
+ | Joystick packet, byte #1
+
+ikbd_yes_joystick:
+#if defined(__mcoldfire__)
+ movel #ikbd_joystick,d0
+ movel d0,0x118:w
+#else
+ movel #ikbd_joystick,0x118:w
+#endif
+ bras ikbd_endit_stack
+
+ | Keyboard press/release
+
+ikbd_no_mouse:
+ moveb d0,d1
+ lea _SDL_AtariIkbd_keyboard,a0
+#if defined(__mcoldfire__)
+ andl #0x7f,d1
+ btst #7,d0
+ spl d0
+ moveb d0,a0@(0,d1:l)
+#else
+ andw #0x7f,d1
+ tas d0
+ spl a0@(0,d1:w)
+#endif
+
+ | End of interrupt
+
+ikbd_endit_stack:
+#if defined(__mcoldfire__)
+ moveql #6,d0
+ bclr d0,0xfffffa11:w
+
+ moveml sp@,d0-d1/a0
+ lea sp@(12),sp
+#else
+ moveml sp@+,d0-d1/a0
+
+ bclr #6,0xfffffa11:w
+#endif
+ rte
+
+ | Call old MIDI interrupt
+
+ikbd_oldmidi:
+#if defined(__mcoldfire__)
+ moveml sp@,d0-d1/a0
+ lea sp@(12),sp
+#else
+ moveml sp@+,d0-d1/a0
+#endif
+
+ movel old_ikbd,sp@-
+ rts
+
+ | Mouse packet, byte #2
+
+ikbd_mousex:
+#if defined(__mcoldfire__)
+ lea sp@(-12),sp
+ moveml d0-d1/a0,sp@
+#else
+ moveml d0-d1/a0,sp@-
+#endif
+
+ | Check if source is IKBD or MIDI
+#if defined(__mcoldfire__)
+ moveql #0,d0
+ btst d0,0xfffffc00.w
+#else
+ btst #0,0xfffffc00.w
+#endif
+ beqs ikbd_oldmidi
+
+ moveb 0xfffffc02:w,d0
+ extw d0
+#if defined(__mcoldfire__)
+ movew _SDL_AtariIkbd_mousex,d1
+ addl d1,d0
+ movew d0,_SDL_AtariIkbd_mousex
+
+ movel #ikbd_mousey,d0
+ movel d0,0x118:w
+#else
+ addw d0,_SDL_AtariIkbd_mousex
+
+ movel #ikbd_mousey,0x118:w
+#endif
+ bras ikbd_endit_stack
+
+ | Mouse packet, byte #3
+
+ikbd_mousey:
+#if defined(__mcoldfire__)
+ lea sp@(-12),sp
+ moveml d0-d1/a0,sp@
+#else
+ moveml d0-d1/a0,sp@-
+#endif
+
+ | Check if source is IKBD or MIDI
+#if defined(__mcoldfire__)
+ moveql #0,d0
+ btst d0,0xfffffc00.w
+#else
+ btst #0,0xfffffc00.w
+#endif
+ beqs ikbd_oldmidi
+
+ moveb 0xfffffc02:w,d0
+ extw d0
+#if defined(__mcoldfire__)
+ movew _SDL_AtariIkbd_mousey,d1
+ addl d1,d0
+ movew d0,_SDL_AtariIkbd_mousey
+
+ movel #ikbd,d0
+ movel d0,0x118:w
+#else
+ addw d0,_SDL_AtariIkbd_mousey
+
+ movel #ikbd,0x118:w
+#endif
+ bras ikbd_endit_stack
+
+ | Joystick packet, byte #2
+
+ikbd_joystick:
+#if defined(__mcoldfire__)
+ lea sp@(-12),sp
+ moveml d0-d1/a0,sp@
+#else
+ moveml d0-d1/a0,sp@-
+#endif
+
+ | Check if source is IKBD or MIDI
+#if defined(__mcoldfire__)
+ moveql #0,d0
+ btst d0,0xfffffc00.w
+#else
+ btst #0,0xfffffc00.w
+#endif
+ beqs ikbd_oldmidi
+
+#if defined(__mcoldfire__)
+ moveb 0xfffffc02:w,d0
+ moveb d0,_SDL_AtariIkbd_joystick+1
+
+ movel #ikbd,d0
+ movel d0,0x118:w
+
+ bra ikbd_endit_stack
+#else
+ moveb 0xfffffc02:w,_SDL_AtariIkbd_joystick+1
+
+ movel #ikbd,0x118:w
+
+ bras ikbd_endit_stack
+#endif
+
+ .data
+
+ .even
+_SDL_AtariIkbd_enabled:
+ .word 0
+
+ .bss
+
+ .even
+ .comm _SDL_AtariIkbd_keyboard,128
+ .comm _SDL_AtariIkbd_mousex,2
+ .comm _SDL_AtariIkbd_mousey,2
+ .comm _SDL_AtariIkbd_mouseb,2
+ .comm _SDL_AtariIkbd_joystick,2
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt_s.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt_s.h
new file mode 100644
index 0000000..ea544bc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_ikbdinterrupt_s.h
@@ -0,0 +1,61 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Mouse vector
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_IKBDINTERRUPT_S_H_
+#define _SDL_IKBDINTERRUPT_S_H_
+
+#include <mint/osbind.h>
+
+#include "SDL_stdinc.h"
+
+/* Const */
+
+#define IKBD_JOY_UP (1<<0)
+#define IKBD_JOY_DOWN (1<<1)
+#define IKBD_JOY_LEFT (1<<2)
+#define IKBD_JOY_RIGHT (1<<3)
+#define IKBD_JOY_FIRE (1<<7)
+
+/* Variables */
+
+extern volatile Uint8 SDL_AtariIkbd_keyboard[128]; /* Keyboard table */
+extern volatile Uint16 SDL_AtariIkbd_mouseb; /* Mouse on port 0, buttons */
+extern volatile Sint16 SDL_AtariIkbd_mousex; /* Mouse X relative motion */
+extern volatile Sint16 SDL_AtariIkbd_mousey; /* Mouse Y relative motion */
+extern volatile Uint16 SDL_AtariIkbd_joystick; /* Joystick on port 1 */
+
+/* For joystick driver to know if this is usable */
+extern Uint16 SDL_AtariIkbd_enabled;
+
+/* Functions */
+
+extern void SDL_AtariIkbdInstall(void);
+extern void SDL_AtariIkbdUninstall(void);
+
+#endif /* _SDL_IKBDINTERRUPT_S_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents.c b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents.c
new file mode 100644
index 0000000..232500f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents.c
@@ -0,0 +1,155 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * XBIOS mouse & joystick vectors
+ *
+ * Patrice Mandin
+ */
+
+#include <mint/osbind.h>
+
+#include "../../events/SDL_events_c.h"
+#include "SDL_atarisuper.h"
+#include "SDL_xbiosevents_c.h"
+#include "SDL_xbiosinterrupt_s.h"
+
+/* Variables */
+
+int SDL_AtariXbios_enabled=0;
+
+/* Local variables */
+
+static _KBDVECS *kbdvecs; /* Pointer to access system vectors */
+static Uint16 atari_prevmouseb; /* buttons */
+
+/* Functions */
+
+void SDL_AtariXbios_InstallVectors(int vectors_mask)
+{
+ void *oldpile;
+
+ /* Clear variables */
+ SDL_AtariXbios_mouselock =
+ SDL_AtariXbios_mouseb =
+ SDL_AtariXbios_mousex =
+ SDL_AtariXbios_mousey =
+ SDL_AtariXbios_joystick =
+ atari_prevmouseb = 0;
+
+ if (vectors_mask==0) {
+ SDL_AtariXbios_enabled=0;
+ return;
+ }
+
+ /* Read IKBD vectors base */
+ kbdvecs=Kbdvbase();
+
+ /* Go to supervisor mode */
+ oldpile=(void *)Super(0);
+
+ /* Install our vectors */
+ SDL_AtariXbios_Install(
+ kbdvecs,
+ (vectors_mask & ATARI_XBIOS_MOUSEEVENTS) ? SDL_AtariXbios_MouseVector : NULL,
+ (vectors_mask & ATARI_XBIOS_JOYSTICKEVENTS) ? SDL_AtariXbios_JoystickVector : NULL
+ );
+
+ /* Back to user mode */
+ SuperToUser(oldpile);
+
+ SDL_AtariXbios_enabled=1;
+}
+
+void SDL_AtariXbios_RestoreVectors(void)
+{
+ void *oldpile;
+
+ if (SDL_AtariXbios_enabled==0) {
+ return;
+ }
+
+ /* Read IKBD vectors base */
+ kbdvecs=Kbdvbase();
+
+ /* Go to supervisor mode */
+ oldpile=(void *)Super(NULL);
+
+ /* Reinstall system vector */
+ SDL_AtariXbios_Restore(kbdvecs);
+
+ /* Back to user mode */
+ SuperToUser(oldpile);
+}
+
+static int atari_GetButton(int button)
+{
+ switch(button)
+ {
+ case 0:
+ return SDL_BUTTON_RIGHT;
+ break;
+ case 1:
+ default:
+ return SDL_BUTTON_LEFT;
+ break;
+ }
+}
+
+void SDL_AtariXbios_PostMouseEvents(_THIS, SDL_bool buttonEvents)
+{
+ if (SDL_AtariXbios_enabled==0) {
+ return;
+ }
+
+ /* Mouse motion ? */
+ if (SDL_AtariXbios_mousex || SDL_AtariXbios_mousey) {
+ SDL_PrivateMouseMotion(0, 1, SDL_AtariXbios_mousex, SDL_AtariXbios_mousey);
+ SDL_AtariXbios_mousex = SDL_AtariXbios_mousey = 0;
+ }
+
+ /* Mouse button ? */
+ if (buttonEvents && (SDL_AtariXbios_mouseb != atari_prevmouseb)) {
+ int i;
+
+ for (i=0;i<2;i++) {
+ int curbutton, prevbutton;
+
+ curbutton = SDL_AtariXbios_mouseb & (1<<i);
+ prevbutton = atari_prevmouseb & (1<<i);
+
+ if (curbutton && !prevbutton) {
+ SDL_PrivateMouseButton(SDL_PRESSED, atari_GetButton(i), 0, 0);
+ }
+ if (!curbutton && prevbutton) {
+ SDL_PrivateMouseButton(SDL_RELEASED, atari_GetButton(i), 0, 0);
+ }
+ }
+ atari_prevmouseb = SDL_AtariXbios_mouseb;
+ }
+}
+
+void SDL_AtariXbios_LockMousePosition(SDL_bool lockPosition)
+{
+ SDL_AtariXbios_mouselock = lockPosition;
+}
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents_c.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents_c.h
new file mode 100644
index 0000000..374b062
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosevents_c.h
@@ -0,0 +1,48 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Xbios mouse & joystick vectors
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_ATARI_XBIOSEVENTS_H_
+#define _SDL_ATARI_XBIOSEVENTS_H_
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define ATARI_XBIOS_MOUSEEVENTS (1<<0)
+#define ATARI_XBIOS_JOYSTICKEVENTS (1<<1)
+
+extern int SDL_AtariXbios_enabled;
+
+extern void SDL_AtariXbios_InstallVectors(int vectors_mask);
+extern void SDL_AtariXbios_RestoreVectors(void);
+extern void SDL_AtariXbios_PostMouseEvents(_THIS, SDL_bool buttonEvents);
+extern void SDL_AtariXbios_LockMousePosition(SDL_bool lockPosition);
+
+#endif /* _SDL_XBIOSEVENTS_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt.S b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt.S
new file mode 100644
index 0000000..3fc1a60
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt.S
@@ -0,0 +1,212 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/*
+ * XBIOS mouse & joystick vectors
+ *
+ * Patrice Mandin
+ */
+
+ .text
+
+ .globl _SDL_AtariXbios_Install
+ .globl _SDL_AtariXbios_Restore
+ .globl _SDL_AtariXbios_MouseVector
+ .globl _SDL_AtariXbios_JoystickVector
+
+ .globl _SDL_AtariXbios_mouselock
+ .globl _SDL_AtariXbios_mouseb
+ .globl _SDL_AtariXbios_mousex
+ .globl _SDL_AtariXbios_mousey
+ .globl _SDL_AtariXbios_joystick
+
+/*--- Vector installer ---*/
+
+_SDL_AtariXbios_Install:
+ movel sp@(4),a0
+
+ /* Stop interrupts */
+
+ movew #0x2700,sr
+
+ /* Save old mouse vector, set our routine */
+
+ clrl oldmousevector
+ movel sp@(8),d0
+ beqs no_new_mouse_vector
+#if defined(__mcoldfire__)
+ movel a0@(16),d1
+ movel d1,oldmousevector
+#else
+ movel a0@(16),oldmousevector
+#endif
+ movel d0,a0@(16)
+no_new_mouse_vector:
+
+ /* Save old joystick vector, set our routine */
+
+ clrl oldjoystickvector
+ movel sp@(12),d0
+ beqs no_new_joystick_vector
+#if defined(__mcoldfire__)
+ movel a0@(24),d1
+ movel d1,oldjoystickvector
+#else
+ movel a0@(24),oldjoystickvector
+#endif
+ movel d0,a0@(24)
+no_new_joystick_vector:
+
+ /* Restart interrupts */
+
+ movew #0x2300,sr
+
+ rts
+
+/*--- Vector restorer ---*/
+
+_SDL_AtariXbios_Restore:
+ movel sp@(4),a0
+
+ /* Stop interrupts */
+
+ movew #0x2700,sr
+
+ /* Restore mouse vector */
+
+ movel oldmousevector,d0
+ beqs no_restore_mouse
+ movel d0,a0@(16)
+no_restore_mouse:
+
+ /* Restore joystick vector */
+
+ movel oldjoystickvector,d0
+ beqs no_restore_joystick
+ movel d0,a0@(24)
+no_restore_joystick:
+
+ /* Restart interrupts */
+
+ movew #0x2300,sr
+
+ rts
+
+/*--- Our mouse vector ---*/
+
+ .text
+ .even
+ .ascii "XBRA"
+ .ascii "LSDL"
+ .comm oldmousevector,4*1
+_SDL_AtariXbios_MouseVector:
+#if defined(__mcoldfire__)
+ lea sp@(-8),sp
+ moveml d0-d1,sp@
+#else
+ movel d0,sp@-
+#endif
+
+ /* Mouse buttons */
+ moveb (a0),d0
+#if defined(__mcoldfire__)
+ andl #3,d0
+#else
+ andw #3,d0
+#endif
+ movew d0,_SDL_AtariXbios_mouseb
+
+ /* X movement */
+ moveb a0@(1),d0
+ extw d0
+#if defined(__mcoldfire__)
+ movew _SDL_AtariXbios_mousex,d1
+ addl d1,d0
+ movew d0,_SDL_AtariXbios_mousex
+#else
+ addw d0,_SDL_AtariXbios_mousex
+#endif
+
+ /* Y movement */
+ moveb a0@(2),d0
+ extw d0
+#if defined(__mcoldfire__)
+ movew _SDL_AtariXbios_mousey,d1
+ addl d1,d0
+ movew d0,_SDL_AtariXbios_mousey
+#else
+ addw d0,_SDL_AtariXbios_mousey
+#endif
+
+ /* Lock mouse position ? */
+ tstw _SDL_AtariXbios_mouselock
+ beq.s no_mouse_lock
+ clrb a0@(1)
+ clrb a0@(2)
+no_mouse_lock:
+
+ /* Jump through old vector */
+#if defined(__mcoldfire__)
+ moveml sp@,d0-d1
+ lea sp@(8),sp
+#else
+ movel sp@+,d0
+#endif
+
+ movel oldmousevector,sp@-
+ rts
+
+ .data
+ .even
+ .comm _SDL_AtariXbios_mouselock,2*1
+ .comm _SDL_AtariXbios_mousex,2*1
+ .comm _SDL_AtariXbios_mousey,2*1
+ .comm _SDL_AtariXbios_mouseb,2*1
+
+/*--- Our joystick vector ---*/
+
+ .text
+ .even
+ .ascii "XBRA"
+ .ascii "LSDL"
+ .comm oldjoystickvector,4*1
+_SDL_AtariXbios_JoystickVector:
+ movel d0,sp@-
+
+ /* New joystick state */
+ moveb a0@(2),d0
+#if defined(__mcoldfire__)
+ andl #0x8f,d0
+#else
+ andw #0x8f,d0
+#endif
+ movew d0,_SDL_AtariXbios_joystick
+
+ /* Jump through old vector */
+ movel sp@+,d0
+
+ movel oldjoystickvector,sp@-
+ rts
+
+ .data
+ .even
+ .comm _SDL_AtariXbios_joystick,2*1
diff --git a/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt_s.h b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt_s.h
new file mode 100644
index 0000000..dfb31c2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ataricommon/SDL_xbiosinterrupt_s.h
@@ -0,0 +1,52 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Mouse vector
+ *
+ * Patrice Mandin
+ */
+
+#ifndef _SDL_XBIOSINTERRUPT_S_H_
+#define _SDL_XBIOSINTERRUPT_S_H_
+
+#include <mint/osbind.h>
+
+#include "SDL_stdinc.h"
+
+/* Variables */
+
+extern volatile Uint16 SDL_AtariXbios_mouselock; /* mouse lock position */
+extern volatile Uint16 SDL_AtariXbios_mouseb; /* buttons */
+extern volatile Sint16 SDL_AtariXbios_mousex; /* X relative motion */
+extern volatile Sint16 SDL_AtariXbios_mousey; /* Y relative motion */
+extern volatile Uint16 SDL_AtariXbios_joystick; /* Joystick */
+
+/* Functions */
+
+extern void SDL_AtariXbios_Install(_KBDVECS *kbdvecs,void *newmousevector,void *newjoystickvector);
+extern void SDL_AtariXbios_Restore(_KBDVECS *kbdvecs);
+extern void SDL_AtariXbios_MouseVector(void *buf);
+extern void SDL_AtariXbios_JoystickVector(void *buf);
+
+#endif /* _SDL_XBIOSINTERRUPT_S_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/blank_cursor.h b/distrib/sdl-1.2.15/src/video/blank_cursor.h
new file mode 100644
index 0000000..db69601
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/blank_cursor.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * A default blank 8x8 cursor */
+
+#define BLANK_CWIDTH 8
+#define BLANK_CHEIGHT 8
+#define BLANK_CHOTX 0
+#define BLANK_CHOTY 0
+
+static unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_BView.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_BView.h
new file mode 100644
index 0000000..bfa2c89
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_BView.h
@@ -0,0 +1,116 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_BView_h
+#define _SDL_BView_h
+
+/* This is the event handling and graphics update portion of SDL_BWin */
+
+extern "C" {
+#include "../../events/SDL_events_c.h"
+};
+
+class SDL_BView : public BView
+{
+public:
+ SDL_BView(BRect frame) :
+ BView(frame, "SDL View", B_FOLLOW_ALL_SIDES,
+ (B_WILL_DRAW|B_FRAME_EVENTS)) {
+ image = NULL;
+ xoff = yoff = 0;
+ SetViewColor(0,0,0,0);
+ SetHighColor(0,0,0,0);
+ }
+ virtual ~SDL_BView() {
+ SetBitmap(NULL);
+ }
+ /* Set drawing offsets for fullscreen mode */
+ virtual void SetXYOffset(int x, int y) {
+ xoff = x;
+ yoff = y;
+ }
+ virtual void GetXYOffset(int &x, int &y) {
+ x = xoff;
+ y = yoff;
+ }
+ virtual void GetXYOffset(float &x, float &y) {
+ x = (float)xoff;
+ y = (float)yoff;
+ }
+ /* The view changed size. If it means we're in fullscreen, we
+ * draw a nice black box in the entire view to get black borders.
+ */
+ virtual void FrameResized(float width, float height) {
+ BRect bounds;
+ bounds.top = bounds.left = 0;
+ bounds.right = width;
+ bounds.bottom = height;
+ /* Fill the entire view with black */
+ FillRect(bounds, B_SOLID_HIGH);
+ /* And if there's an image, redraw it. */
+ if( image ) {
+ bounds = image->Bounds();
+ Draw(bounds);
+ }
+ }
+
+ /* Drawing portion of this complete breakfast. :) */
+ virtual void SetBitmap(BBitmap *bitmap) {
+ if ( image ) {
+ delete image;
+ }
+ image = bitmap;
+ }
+ virtual void Draw(BRect updateRect) {
+ if ( image ) {
+ if(xoff || yoff) {
+ BRect dest;
+ dest.top = updateRect.top + yoff;
+ dest.left = updateRect.left + xoff;
+ dest.bottom = updateRect.bottom + yoff;
+ dest.right = updateRect.right + xoff;
+ DrawBitmap(image, updateRect, dest);
+ } else {
+ DrawBitmap(image, updateRect, updateRect);
+ }
+ }
+ }
+ virtual void DrawAsync(BRect updateRect) {
+ if(xoff || yoff) {
+ BRect dest;
+ dest.top = updateRect.top + yoff;
+ dest.left = updateRect.left + xoff;
+ dest.bottom = updateRect.bottom + yoff;
+ dest.right = updateRect.right + xoff;;
+ DrawBitmapAsync(image, updateRect, dest);
+ } else {
+ DrawBitmapAsync(image, updateRect, updateRect);
+ }
+ }
+
+private:
+ BBitmap *image;
+ int xoff, yoff;
+};
+
+#endif /* _SDL_BView_h */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_BWin.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_BWin.h
new file mode 100644
index 0000000..f2b19a2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_BWin.h
@@ -0,0 +1,290 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_BWin_h
+#define _SDL_BWin_h
+
+#include "SDL_config.h"
+
+#include <stdio.h>
+#include <AppKit.h>
+#include <InterfaceKit.h>
+#include <be/game/DirectWindow.h>
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#include <be/opengl/GLView.h>
+#endif
+#include <support/UTF8.h>
+
+#include "../../main/beos/SDL_BeApp.h"
+#include "SDL_events.h"
+#include "SDL_BView.h"
+
+extern "C" {
+#include "../../events/SDL_events_c.h"
+
+extern int mouse_relative;
+};
+
+class SDL_BWin : public BDirectWindow
+{
+public:
+ SDL_BWin(BRect bounds) :
+ BDirectWindow(bounds, "Untitled", B_TITLED_WINDOW, 0) {
+ last_buttons = 0;
+ the_view = NULL;
+#if SDL_VIDEO_OPENGL
+ SDL_GLView = NULL;
+#endif
+ SDL_View = NULL;
+ Unlock();
+ shown = false;
+ inhibit_resize = false;
+ }
+
+ virtual ~SDL_BWin() {
+ Lock();
+ if ( the_view ) {
+#if SDL_VIDEO_OPENGL
+ if ( the_view == SDL_GLView ) {
+ SDL_GLView->UnlockGL();
+ }
+#endif
+ RemoveChild(the_view);
+ the_view = NULL;
+ }
+ Unlock();
+#if SDL_VIDEO_OPENGL
+ if ( SDL_GLView ) {
+ delete SDL_GLView;
+ }
+#endif
+ if ( SDL_View ) {
+ delete SDL_View;
+ }
+ }
+
+
+ /* Override the Show() method so we can tell when we've been shown */
+ virtual void Show(void) {
+ BWindow::Show();
+ shown = true;
+ }
+ virtual bool Shown(void) {
+ return (shown);
+ }
+ /* If called, the next resize event will not be forwarded to SDL. */
+ virtual void InhibitResize(void) {
+ inhibit_resize=true;
+ }
+ /* Handle resizing of the window */
+ virtual void FrameResized(float width, float height) {
+ if(inhibit_resize)
+ inhibit_resize = false;
+ else
+ SDL_PrivateResize((int)width, (int)height);
+ }
+ virtual int CreateView(Uint32 flags, Uint32 gl_flags) {
+ int retval;
+
+ retval = 0;
+ Lock();
+ if ( flags & SDL_OPENGL ) {
+#if SDL_VIDEO_OPENGL
+ if ( SDL_GLView == NULL ) {
+ SDL_GLView = new BGLView(Bounds(), "SDL GLView",
+ B_FOLLOW_ALL_SIDES, (B_WILL_DRAW|B_FRAME_EVENTS),
+ gl_flags|BGL_DOUBLE);
+ SDL_GLView->EnableDirectMode(true);
+ }
+ if ( the_view != SDL_GLView ) {
+ if ( the_view ) {
+ RemoveChild(the_view);
+ }
+ AddChild(SDL_GLView);
+ SDL_GLView->LockGL();
+ the_view = SDL_GLView;
+ }
+#else
+ SDL_SetError("OpenGL support not enabled");
+ retval = -1;
+#endif
+ } else {
+ if ( SDL_View == NULL ) {
+ SDL_View = new SDL_BView(Bounds());
+ }
+ if ( the_view != SDL_View ) {
+ if ( the_view ) {
+ RemoveChild(the_view);
+ }
+ AddChild(SDL_View);
+ the_view = SDL_View;
+ }
+ }
+#if SDL_VIDEO_OPENGL
+ if ( the_view == SDL_GLView ) {
+ SDL_GLView->UnlockGL();
+ }
+#endif
+ Unlock();
+ return(retval);
+ }
+ virtual void SetBitmap(BBitmap *bitmap) {
+ SDL_View->SetBitmap(bitmap);
+ }
+ virtual void SetXYOffset(int x, int y) {
+#if SDL_VIDEO_OPENGL
+ if ( the_view == SDL_GLView ) {
+ return;
+ }
+#endif
+ SDL_View->SetXYOffset(x, y);
+ }
+ virtual void GetXYOffset(int &x, int &y) {
+#if SDL_VIDEO_OPENGL
+ if ( the_view == SDL_GLView ) {
+ x = 0;
+ y = 0;
+ return;
+ }
+#endif
+ SDL_View->GetXYOffset(x, y);
+ }
+ virtual void GetXYOffset(float &x, float &y) {
+#if SDL_VIDEO_OPENGL
+ if ( the_view == SDL_GLView ) {
+ x = 0.0f;
+ y = 0.0f;
+ return;
+ }
+#endif
+ SDL_View->GetXYOffset(x, y);
+ }
+ virtual bool BeginDraw(void) {
+ return(Lock());
+ }
+ virtual void DrawAsync(BRect updateRect) {
+ SDL_View->DrawAsync(updateRect);
+ }
+ virtual void EndDraw(void) {
+ SDL_View->Sync();
+ Unlock();
+ }
+#if SDL_VIDEO_OPENGL
+ virtual void SwapBuffers(void) {
+ SDL_GLView->UnlockGL();
+ SDL_GLView->SwapBuffers();
+ SDL_GLView->LockGL();
+ }
+#endif
+ virtual BView *View(void) {
+ return(the_view);
+ }
+
+ /* Hook functions -- overridden */
+ virtual void Minimize(bool minimize) {
+ /* This is only called when mimimized, not when restored */
+ //SDL_PrivateAppActive(minimize, SDL_APPACTIVE);
+ BWindow::Minimize(minimize);
+ }
+ virtual void WindowActivated(bool active) {
+ SDL_PrivateAppActive(active, SDL_APPINPUTFOCUS);
+ }
+ virtual bool QuitRequested(void) {
+ if ( SDL_BeAppActive > 0 ) {
+ SDL_PrivateQuit();
+ /* We don't ever actually close the window here because
+ the application should respond to the quit request,
+ or ignore it as desired.
+ */
+#if SDL_VIDEO_OPENGL
+ if ( SDL_GLView != NULL ) {
+ SDL_GLView->EnableDirectMode(false);
+ }
+#endif
+ return(false);
+ }
+ return(true); /* Close the app window */
+ }
+ virtual void Quit() {
+ if (!IsLocked())
+ Lock();
+ BDirectWindow::Quit();
+ }
+
+ virtual int16 Translate2Unicode(const char *buf) {
+ int32 state, srclen, dstlen;
+ unsigned char destbuf[2];
+ Uint16 unicode = 0;
+
+ if ((uchar)buf[0] > 127) {
+ state = 0;
+ srclen = SDL_strlen(buf);
+ dstlen = sizeof(destbuf);
+ convert_from_utf8(B_UNICODE_CONVERSION, buf, &srclen, (char *)destbuf, &dstlen, &state);
+ unicode = destbuf[0];
+ unicode <<= 8;
+ unicode |= destbuf[1];
+ } else
+ unicode = buf[0];
+
+ /* For some reason function keys map to control characters */
+# define CTRL(X) ((X)-'@')
+ switch (unicode) {
+ case CTRL('A'):
+ case CTRL('B'):
+ case CTRL('C'):
+ case CTRL('D'):
+ case CTRL('E'):
+ case CTRL('K'):
+ case CTRL('L'):
+ case CTRL('P'):
+ if ( ! (SDL_GetModState() & KMOD_CTRL) )
+ unicode = 0;
+ break;
+ /* Keyboard input maps newline to carriage return */
+ case '\n':
+ unicode = '\r';
+ break;
+ default:
+ break;
+ }
+
+ return unicode;
+ }
+
+ virtual void DispatchMessage(BMessage *msg, BHandler *target);
+
+ virtual void DirectConnected(direct_buffer_info *info);
+
+private:
+#if SDL_VIDEO_OPENGL
+ BGLView *SDL_GLView;
+#endif
+ SDL_BView *SDL_View;
+ BView *the_view;
+ bool shown;
+ bool inhibit_resize;
+ int32 last_buttons;
+};
+
+#endif /* _SDL_BWin_h */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_lowvideo.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_lowvideo.h
new file mode 100644
index 0000000..0513b2d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_lowvideo.h
@@ -0,0 +1,58 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_lowvideo_h
+#define _SDL_lowvideo_h
+
+#include "SDL_BWin.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *_this
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ /* The main window */
+ SDL_BWin *SDL_Win;
+
+ /* The fullscreen mode list */
+ display_mode saved_mode;
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+ /* A completely clear cursor */
+ WMcursor *BlankCursor;
+
+ SDL_Overlay *overlay;
+};
+/* Old variable names */
+#define SDL_Win (_this->hidden->SDL_Win)
+#define saved_mode (_this->hidden->saved_mode)
+#define SDL_nummodes (_this->hidden->SDL_nummodes)
+#define SDL_modelist (_this->hidden->SDL_modelist)
+#define SDL_BlankCursor (_this->hidden->BlankCursor)
+#define current_overlay (_this->hidden->overlay)
+
+#endif /* _SDL_lowvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents.cc
new file mode 100644
index 0000000..9e12750
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents.cc
@@ -0,0 +1,415 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <support/UTF8.h>
+#include <stdio.h>
+#include <string.h>
+#include "SDL_error.h"
+#include "SDL_events.h"
+#include "SDL_BWin.h"
+#include "SDL_lowvideo.h"
+
+static SDLKey keymap[128];
+int mouse_relative = 0;
+extern "C" {
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_sysevents_c.h"
+#include "../SDL_cursor_c.h"
+
+void BE_PumpEvents(_THIS)
+{
+}
+
+void BE_InitOSKeymap(_THIS)
+{
+ for ( uint i=0; i<SDL_TABLESIZE(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[0x01] = SDLK_ESCAPE;
+ keymap[B_F1_KEY] = SDLK_F1;
+ keymap[B_F2_KEY] = SDLK_F2;
+ keymap[B_F3_KEY] = SDLK_F3;
+ keymap[B_F4_KEY] = SDLK_F4;
+ keymap[B_F5_KEY] = SDLK_F5;
+ keymap[B_F6_KEY] = SDLK_F6;
+ keymap[B_F7_KEY] = SDLK_F7;
+ keymap[B_F8_KEY] = SDLK_F8;
+ keymap[B_F9_KEY] = SDLK_F9;
+ keymap[B_F10_KEY] = SDLK_F10;
+ keymap[B_F11_KEY] = SDLK_F11;
+ keymap[B_F12_KEY] = SDLK_F12;
+ keymap[B_PRINT_KEY] = SDLK_PRINT;
+ keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
+ keymap[B_PAUSE_KEY] = SDLK_PAUSE;
+ keymap[0x11] = SDLK_BACKQUOTE;
+ keymap[0x12] = SDLK_1;
+ keymap[0x13] = SDLK_2;
+ keymap[0x14] = SDLK_3;
+ keymap[0x15] = SDLK_4;
+ keymap[0x16] = SDLK_5;
+ keymap[0x17] = SDLK_6;
+ keymap[0x18] = SDLK_7;
+ keymap[0x19] = SDLK_8;
+ keymap[0x1a] = SDLK_9;
+ keymap[0x1b] = SDLK_0;
+ keymap[0x1c] = SDLK_MINUS;
+ keymap[0x1d] = SDLK_EQUALS;
+ keymap[0x1e] = SDLK_BACKSPACE;
+ keymap[0x1f] = SDLK_INSERT;
+ keymap[0x20] = SDLK_HOME;
+ keymap[0x21] = SDLK_PAGEUP;
+ keymap[0x22] = SDLK_NUMLOCK;
+ keymap[0x23] = SDLK_KP_DIVIDE;
+ keymap[0x24] = SDLK_KP_MULTIPLY;
+ keymap[0x25] = SDLK_KP_MINUS;
+ keymap[0x26] = SDLK_TAB;
+ keymap[0x27] = SDLK_q;
+ keymap[0x28] = SDLK_w;
+ keymap[0x29] = SDLK_e;
+ keymap[0x2a] = SDLK_r;
+ keymap[0x2b] = SDLK_t;
+ keymap[0x2c] = SDLK_y;
+ keymap[0x2d] = SDLK_u;
+ keymap[0x2e] = SDLK_i;
+ keymap[0x2f] = SDLK_o;
+ keymap[0x30] = SDLK_p;
+ keymap[0x31] = SDLK_LEFTBRACKET;
+ keymap[0x32] = SDLK_RIGHTBRACKET;
+ keymap[0x33] = SDLK_BACKSLASH;
+ keymap[0x34] = SDLK_DELETE;
+ keymap[0x35] = SDLK_END;
+ keymap[0x36] = SDLK_PAGEDOWN;
+ keymap[0x37] = SDLK_KP7;
+ keymap[0x38] = SDLK_KP8;
+ keymap[0x39] = SDLK_KP9;
+ keymap[0x3a] = SDLK_KP_PLUS;
+ keymap[0x3b] = SDLK_CAPSLOCK;
+ keymap[0x3c] = SDLK_a;
+ keymap[0x3d] = SDLK_s;
+ keymap[0x3e] = SDLK_d;
+ keymap[0x3f] = SDLK_f;
+ keymap[0x40] = SDLK_g;
+ keymap[0x41] = SDLK_h;
+ keymap[0x42] = SDLK_j;
+ keymap[0x43] = SDLK_k;
+ keymap[0x44] = SDLK_l;
+ keymap[0x45] = SDLK_SEMICOLON;
+ keymap[0x46] = SDLK_QUOTE;
+ keymap[0x47] = SDLK_RETURN;
+ keymap[0x48] = SDLK_KP4;
+ keymap[0x49] = SDLK_KP5;
+ keymap[0x4a] = SDLK_KP6;
+ keymap[0x4b] = SDLK_LSHIFT;
+ keymap[0x4c] = SDLK_z;
+ keymap[0x4d] = SDLK_x;
+ keymap[0x4e] = SDLK_c;
+ keymap[0x4f] = SDLK_v;
+ keymap[0x50] = SDLK_b;
+ keymap[0x51] = SDLK_n;
+ keymap[0x52] = SDLK_m;
+ keymap[0x53] = SDLK_COMMA;
+ keymap[0x54] = SDLK_PERIOD;
+ keymap[0x55] = SDLK_SLASH;
+ keymap[0x56] = SDLK_RSHIFT;
+ keymap[0x57] = SDLK_UP;
+ keymap[0x58] = SDLK_KP1;
+ keymap[0x59] = SDLK_KP2;
+ keymap[0x5a] = SDLK_KP3;
+ keymap[0x5b] = SDLK_KP_ENTER;
+ keymap[0x5c] = SDLK_LCTRL;
+ keymap[0x5d] = SDLK_LALT;
+ keymap[0x5e] = SDLK_SPACE;
+ keymap[0x5f] = SDLK_RALT;
+ keymap[0x60] = SDLK_RCTRL;
+ keymap[0x61] = SDLK_LEFT;
+ keymap[0x62] = SDLK_DOWN;
+ keymap[0x63] = SDLK_RIGHT;
+ keymap[0x64] = SDLK_KP0;
+ keymap[0x65] = SDLK_KP_PERIOD;
+ keymap[0x66] = SDLK_LMETA;
+ keymap[0x67] = SDLK_RMETA;
+ keymap[0x68] = SDLK_MENU;
+ keymap[0x69] = SDLK_EURO;
+ keymap[0x6a] = SDLK_KP_EQUALS;
+ keymap[0x6b] = SDLK_POWER;
+}
+
+}; /* Extern C */
+
+void SDL_BWin::DispatchMessage(BMessage *msg, BHandler *target)
+{
+ switch (msg->what) {
+ case B_MOUSE_MOVED:
+ {
+ SDL_VideoDevice *view = current_video;
+ BPoint where;
+ int32 transit;
+ if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) {
+ int x, y;
+
+ GetXYOffset(x, y);
+ x = (int)where.x - x;
+ y = (int)where.y - y;
+
+ //BeSman: I need another method for cursor catching !!!
+ if (view->input_grab != SDL_GRAB_OFF)
+ {
+ bool clipped = false;
+ if ( x < 0 ) {
+ x = 0;
+ clipped = true;
+ } else if ( x >= SDL_VideoSurface->w ) {
+ x = (SDL_VideoSurface->w-1);
+ clipped = true;
+ }
+ if ( y < 0 ) {
+ y = 0;
+ clipped = true;
+ } else if ( y >= SDL_VideoSurface->h ) {
+ y = (SDL_VideoSurface->h-1);
+ clipped = true;
+ }
+ if ( clipped ) {
+ BPoint edge;
+ GetXYOffset(edge.x, edge.y);
+ edge.x += x;
+ edge.y += y;
+ ConvertToScreen(&edge);
+ set_mouse_position((int)edge.x, (int)edge.y);
+ }
+ transit = B_INSIDE_VIEW;
+ }
+ if (transit == B_EXITED_VIEW) {
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+#if SDL_VIDEO_OPENGL
+ // for some reason, SDL_EraseCursor fails for OpenGL
+ if (this->the_view != this->SDL_GLView)
+#endif
+ SDL_EraseCursor(SDL_VideoSurface);
+ be_app->SetCursor(B_HAND_CURSOR);
+ }
+ } else {
+ if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+#if SDL_VIDEO_OPENGL
+ // for some reason, SDL_EraseCursor fails for OpenGL
+ if (this->the_view != this->SDL_GLView)
+#endif
+ SDL_EraseCursor(SDL_VideoSurface);
+ SDL_SetCursor(NULL);
+ }
+
+ if ( mouse_relative ) {
+ int half_w = (SDL_VideoSurface->w/2);
+ int half_h = (SDL_VideoSurface->h/2);
+ x -= half_w;
+ y -= half_h;
+ if ( x || y ) {
+ BPoint center;
+ GetXYOffset(center.x, center.y);
+ center.x += half_w;
+ center.y += half_h;
+ ConvertToScreen(&center);
+ set_mouse_position((int)center.x, (int)center.y);
+ SDL_PrivateMouseMotion(0, 1, x, y);
+ }
+ } else {
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ }
+ }
+ }
+ break;
+ }
+
+ case B_MOUSE_DOWN:
+ {
+ /* it looks like mouse down is send only for first clicked
+ button, each next is not send while last one is holded */
+ int32 buttons;
+ int sdl_buttons = 0;
+ if (msg->FindInt32("buttons", &buttons) == B_OK) {
+ /* Add any mouse button events */
+ if (buttons & B_PRIMARY_MOUSE_BUTTON) {
+ sdl_buttons |= SDL_BUTTON_LEFT;
+ }
+ if (buttons & B_SECONDARY_MOUSE_BUTTON) {
+ sdl_buttons |= SDL_BUTTON_RIGHT;
+ }
+ if (buttons & B_TERTIARY_MOUSE_BUTTON) {
+ sdl_buttons |= SDL_BUTTON_MIDDLE;
+ }
+ SDL_PrivateMouseButton(SDL_PRESSED, sdl_buttons, 0, 0);
+
+ last_buttons = buttons;
+ }
+ break;
+ }
+
+ case B_MOUSE_UP:
+ {
+ /* mouse up doesn't give which button was released,
+ only state of buttons (after release, so it's always = 0),
+ which is not what we need ;]
+ So we need to store button in mouse down, and restore
+ in mouse up :(
+ mouse up is (similarly to mouse down) send only for
+ first button down (ie. it's no send if we click another button
+ without releasing previous one first) - but that's probably
+ because of how drivers are written?, not BeOS itself. */
+ int32 buttons;
+ int sdl_buttons = 0;
+ if (msg->FindInt32("buttons", &buttons) == B_OK) {
+ /* Add any mouse button events */
+ if ((buttons ^ B_PRIMARY_MOUSE_BUTTON) & last_buttons) {
+ sdl_buttons |= SDL_BUTTON_LEFT;
+ }
+ if ((buttons ^ B_SECONDARY_MOUSE_BUTTON) & last_buttons) {
+ sdl_buttons |= SDL_BUTTON_RIGHT;
+ }
+ if ((buttons ^ B_TERTIARY_MOUSE_BUTTON) & last_buttons) {
+ sdl_buttons |= SDL_BUTTON_MIDDLE;
+ }
+ SDL_PrivateMouseButton(SDL_RELEASED, sdl_buttons, 0, 0);
+
+ last_buttons = buttons;
+ }
+ break;
+ }
+
+ case B_MOUSE_WHEEL_CHANGED:
+ {
+ float x, y;
+ x = y = 0;
+ if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) {
+ if (x < 0 || y < 0) {
+ SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ } else if (x > 0 || y > 0) {
+ SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
+ SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
+ }
+ }
+ break;
+ }
+
+ case B_KEY_DOWN:
+ case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
+ {
+ int32 key;
+ int32 modifiers;
+ int32 key_repeat;
+ /* Workaround for SDL message queue being filled too fast because of BeOS own key-repeat mechanism */
+ if (msg->FindInt32("be:key_repeat", &key_repeat) == B_OK && key_repeat > 0)
+ break;
+
+ if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
+ SDL_keysym keysym;
+ keysym.scancode = key;
+ if (key < 128) {
+ keysym.sym = keymap[key];
+ } else {
+ keysym.sym = SDLK_UNKNOWN;
+ }
+ /* FIX THIS?
+ it seems SDL_PrivateKeyboard() changes mod value
+ anyway, and doesn't care about what we setup here */
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ if (SDL_TranslateUNICODE) {
+ const char *bytes;
+ if (msg->FindString("bytes", &bytes) == B_OK) {
+ /* FIX THIS?
+ this cares only about first "letter",
+ so if someone maps some key to print
+ "BeOS rulez!" only "B" will be used. */
+ keysym.unicode = Translate2Unicode(bytes);
+ }
+ }
+ SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ break;
+ }
+
+ case B_KEY_UP:
+ case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
+ {
+ int32 key;
+ int32 modifiers;
+ if (msg->FindInt32("key", &key) == B_OK && msg->FindInt32("modifiers", &modifiers) == B_OK) {
+ SDL_keysym keysym;
+ keysym.scancode = key;
+ if (key < 128) {
+ keysym.sym = keymap[key];
+ } else {
+ keysym.sym = SDLK_UNKNOWN;
+ }
+ keysym.mod = KMOD_NONE; /* FIX THIS? */
+ keysym.unicode = 0;
+ if (SDL_TranslateUNICODE) {
+ const char *bytes;
+ if (msg->FindString("bytes", &bytes) == B_OK) {
+ keysym.unicode = Translate2Unicode(bytes);
+ }
+ }
+ SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+ }
+ break;
+ }
+
+ default:
+ /* move it after switch{} so it's always handled
+ that way we keep BeOS feautures like:
+ - CTRL+Q to close window (and other shortcuts)
+ - PrintScreen to make screenshot into /boot/home
+ - etc.. */
+ //BDirectWindow::DispatchMessage(msg, target);
+ break;
+ }
+ BDirectWindow::DispatchMessage(msg, target);
+}
+
+void SDL_BWin::DirectConnected(direct_buffer_info *info) {
+ switch (info->buffer_state & B_DIRECT_MODE_MASK) {
+ case B_DIRECT_START:
+ case B_DIRECT_MODIFY:
+ {
+ int32 width = info->window_bounds.right -
+ info->window_bounds.left;
+ int32 height = info->window_bounds.bottom -
+ info->window_bounds.top;
+ SDL_PrivateResize(width, height);
+ break;
+ }
+ default:
+ break;
+ }
+#if SDL_VIDEO_OPENGL
+ // If it is a BGLView, it is apparently required to
+ // call DirectConnected() on it as well
+ if (this->the_view == this->SDL_GLView)
+ this->SDL_GLView->DirectConnected(info);
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents_c.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents_c.h
new file mode 100644
index 0000000..70c5535
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysevents_c.h
@@ -0,0 +1,31 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+
+extern void BE_InitOSKeymap(_THIS);
+extern void BE_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse.cc
new file mode 100644
index 0000000..9a557d6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse.cc
@@ -0,0 +1,153 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <AppKit.h>
+#include <GameKit.h>
+
+#include "SDL_BWin.h"
+
+extern "C" {
+#include "../SDL_cursor_c.h"
+#include "SDL_sysmouse_c.h"
+
+/* Convert bits to padded bytes */
+#define PADDED_BITS(bits) ((bits+7)/8)
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ char *bits;
+};
+
+/* Can this be done in the BeOS? */
+WMcursor *BE_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ int allowed_x;
+ int allowed_y;
+ int run, pad, i;
+ char *cptr;
+
+ allowed_x = 16; /* BeOS limitation */
+ allowed_y = 16; /* BeOS limitation */
+ if ( (w > allowed_x) || (h > allowed_y) ) {
+ SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
+ allowed_x, allowed_y);
+ return(NULL);
+ }
+
+ /* Allocate the cursor */
+ cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
+ if ( cursor == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ cursor->bits = (char *)SDL_malloc(4+2*((allowed_x/8)*allowed_y));
+ if ( cursor->bits == NULL ) {
+ SDL_free(cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ cursor->bits[0] = allowed_y; /* Size of the cursor */
+ cursor->bits[1] = 1; /* Bit depth of cursor */
+ cursor->bits[2] = hot_y;
+ cursor->bits[3] = hot_x;
+ cptr = &cursor->bits[4];
+
+ /* Pad out to the normal cursor size */
+ run = PADDED_BITS(w);
+ pad = PADDED_BITS(allowed_x)-run;
+ for ( i=0; i<h; ++i ) {
+ SDL_memcpy(cptr, data, run);
+ SDL_memset(cptr+run, 0, pad);
+ data += run;
+ cptr += (run+pad);
+ }
+ for ( ; i<allowed_y; ++i ) {
+ SDL_memset(cptr, 0, run+pad);
+ cptr += (run+pad);
+ }
+ for ( i=0; i<h; ++i ) {
+ /* FIXME: The mask should be OR'd with the data to turn
+ inverted color pixels black, since inverted color pixels
+ aren't supported under BeOS.
+ */
+ SDL_memcpy(cptr, mask, run);
+ SDL_memset(cptr+run, 0, pad);
+ mask += run;
+ cptr += (run+pad);
+ }
+ for ( ; i<allowed_y; ++i ) {
+ SDL_memset(cptr, 0, run+pad);
+ cptr += (run+pad);
+ }
+ return(cursor);
+}
+
+int BE_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ if ( be_app->Lock() ) {
+ if ( cursor == NULL ) {
+ if ( SDL_BlankCursor != NULL ) {
+ be_app->SetCursor(SDL_BlankCursor->bits);
+ }
+ } else {
+ be_app->SetCursor(cursor->bits);
+ }
+ be_app->Unlock();
+ }
+ return(1);
+}
+
+void BE_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ SDL_free(cursor->bits);
+ SDL_free(cursor);
+}
+
+/* Implementation by Christian Bauer <cbauer@student.physik.uni-mainz.de> */
+void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ BPoint pt;
+ SDL_Win->GetXYOffset(pt.x, pt.y);
+ pt.x += x;
+ pt.y += y;
+ SDL_Win->Lock();
+ SDL_Win->ConvertToScreen(&pt);
+ SDL_Win->Unlock();
+ set_mouse_position((int32)pt.x, (int32)pt.y);
+}
+
+/* Check to see if we need to enter or leave mouse relative mode */
+void BE_CheckMouseMode(_THIS)
+{
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
+ (_this->input_grab != SDL_GRAB_OFF) ) {
+ mouse_relative = 1;
+ } else {
+ mouse_relative = 0;
+ }
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse_c.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse_c.h
new file mode 100644
index 0000000..70b3b2a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysmouse_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Functions to be exported */
+extern void BE_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *BE_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int BE_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void BE_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+extern void BE_CheckMouseMode(_THIS);
+
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysvideo.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysvideo.cc
new file mode 100644
index 0000000..c32b661
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysvideo.cc
@@ -0,0 +1,841 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* BWindow based framebuffer implementation */
+
+#include <unistd.h>
+
+#include "SDL_BWin.h"
+#include "SDL_timer.h"
+
+extern "C" {
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_sysevents_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_lowvideo.h"
+#include "../SDL_yuvfuncs.h"
+#include "SDL_sysyuv.h"
+#include "../blank_cursor.h"
+
+#define BEOS_HIDDEN_SIZE 32 /* starting hidden window size */
+
+/* Initialization/Query functions */
+static int BE_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static void BE_UpdateMouse(_THIS);
+static int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void BE_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int BE_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int BE_LockHWSurface(_THIS, SDL_Surface *surface);
+static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void BE_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+static int BE_ToggleFullScreen(_THIS, int fullscreen);
+
+/* OpenGL functions */
+#if SDL_VIDEO_OPENGL
+static int BE_GL_LoadLibrary(_THIS, const char *path);
+static void* BE_GL_GetProcAddress(_THIS, const char *proc);
+static int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+static int BE_GL_MakeCurrent(_THIS);
+static void BE_GL_SwapBuffers(_THIS);
+#endif
+
+/* FB driver bootstrap functions */
+
+static int BE_Available(void)
+{
+ return(1);
+}
+
+static void BE_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *BE_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ /* Initialization/Query functions */
+ device->VideoInit = BE_VideoInit;
+ device->ListModes = BE_ListModes;
+ device->SetVideoMode = BE_SetVideoMode;
+ device->ToggleFullScreen = BE_ToggleFullScreen;
+ device->UpdateMouse = BE_UpdateMouse;
+ device->CreateYUVOverlay = BE_CreateYUVOverlay;
+ device->SetColors = BE_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = BE_VideoQuit;
+ /* Hardware acceleration functions */
+ device->AllocHWSurface = BE_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = BE_LockHWSurface;
+ device->UnlockHWSurface = BE_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = BE_FreeHWSurface;
+ /* Gamma support */
+#if SDL_VIDEO_OPENGL
+ /* OpenGL support */
+ device->GL_LoadLibrary = BE_GL_LoadLibrary;
+ device->GL_GetProcAddress = BE_GL_GetProcAddress;
+ device->GL_GetAttribute = BE_GL_GetAttribute;
+ device->GL_MakeCurrent = BE_GL_MakeCurrent;
+ device->GL_SwapBuffers = BE_GL_SwapBuffers;
+#endif
+ /* Window manager functions */
+ device->SetCaption = BE_SetWMCaption;
+ device->SetIcon = NULL;
+ device->IconifyWindow = BE_IconifyWindow;
+ device->GrabInput = BE_GrabInput;
+ device->GetWMInfo = BE_GetWMInfo;
+ /* Cursor manager functions */
+ device->FreeWMCursor = BE_FreeWMCursor;
+ device->CreateWMCursor = BE_CreateWMCursor;
+ device->ShowWMCursor = BE_ShowWMCursor;
+ device->WarpWMCursor = BE_WarpWMCursor;
+ device->MoveWMCursor = NULL;
+ device->CheckMouseMode = BE_CheckMouseMode;
+ /* Event manager functions */
+ device->InitOSKeymap = BE_InitOSKeymap;
+ device->PumpEvents = BE_PumpEvents;
+
+ device->free = BE_DeleteDevice;
+
+ /* Set the driver flags */
+ device->handles_any_size = 1;
+
+ return device;
+}
+
+VideoBootStrap BWINDOW_bootstrap = {
+ "bwindow", "BDirectWindow graphics",
+ BE_Available, BE_CreateDevice
+};
+
+static inline int ColorSpaceToBitsPerPixel(uint32 colorspace)
+{
+ int bitsperpixel;
+
+ bitsperpixel = 0;
+ switch (colorspace) {
+ case B_CMAP8:
+ bitsperpixel = 8;
+ break;
+ case B_RGB15:
+ case B_RGBA15:
+ case B_RGB15_BIG:
+ case B_RGBA15_BIG:
+ bitsperpixel = 15;
+ break;
+ case B_RGB16:
+ case B_RGB16_BIG:
+ bitsperpixel = 16;
+ break;
+ case B_RGB32:
+ case B_RGBA32:
+ case B_RGB32_BIG:
+ case B_RGBA32_BIG:
+ bitsperpixel = 32;
+ break;
+ default:
+ break;
+ }
+ return(bitsperpixel);
+}
+
+/* Function to sort the display_list in bscreen */
+static int CompareModes(const void *A, const void *B)
+{
+ const display_mode *a = (display_mode *)A;
+ const display_mode *b = (display_mode *)B;
+
+ if ( a->space == b->space ) {
+ return((b->virtual_width*b->virtual_height)-
+ (a->virtual_width*a->virtual_height));
+ } else {
+ return(ColorSpaceToBitsPerPixel(b->space)-
+ ColorSpaceToBitsPerPixel(a->space));
+ }
+}
+
+/* Yes, this isn't the fastest it could be, but it works nicely */
+static int BE_AddMode(_THIS, int index, unsigned int w, unsigned int h)
+{
+ SDL_Rect *mode;
+ int i;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( SDL_nummodes[index] > 0 ) {
+ for ( i=SDL_nummodes[index]-1; i >= 0; --i ) {
+ mode = SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+#ifdef BWINDOW_DEBUG
+ fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1);
+#endif
+ return(0);
+ }
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+#ifdef BWINDOW_DEBUG
+ fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1);
+#endif
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+int BE_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ display_mode *modes;
+ uint32 i, nmodes;
+ int bpp;
+ BRect bounds;
+
+ /* Initialize the Be Application for appserver interaction */
+ if ( SDL_InitBeApp() < 0 ) {
+ return(-1);
+ }
+
+ /* It is important that this be created after SDL_InitBeApp() */
+ BScreen bscreen;
+
+ /* Save the current display mode */
+ bscreen.GetMode(&saved_mode);
+ _this->info.current_w = saved_mode.virtual_width;
+ _this->info.current_h = saved_mode.virtual_height;
+
+ /* Determine the screen depth */
+ vformat->BitsPerPixel = ColorSpaceToBitsPerPixel(bscreen.ColorSpace());
+ if ( vformat->BitsPerPixel == 0 ) {
+ SDL_SetError("Unknown BScreen colorspace: 0x%x",
+ bscreen.ColorSpace());
+ return(-1);
+ }
+
+ /* Get the video modes we can switch to in fullscreen mode */
+ bscreen.GetModeList(&modes, &nmodes);
+ SDL_qsort(modes, nmodes, sizeof *modes, CompareModes);
+ for ( i=0; i<nmodes; ++i ) {
+ bpp = ColorSpaceToBitsPerPixel(modes[i].space);
+ //if ( bpp != 0 ) { // There are bugs in changing colorspace
+ if ( modes[i].space == saved_mode.space ) {
+ BE_AddMode(_this, ((bpp+7)/8)-1,
+ modes[i].virtual_width,
+ modes[i].virtual_height);
+ }
+ }
+
+ /* Create the window and view */
+ bounds.top = 0; bounds.left = 0;
+ bounds.right = BEOS_HIDDEN_SIZE;
+ bounds.bottom = BEOS_HIDDEN_SIZE;
+ SDL_Win = new SDL_BWin(bounds);
+
+#if SDL_VIDEO_OPENGL
+ /* testgl application doesn't load library, just tries to load symbols */
+ /* is it correct? if so we have to load library here */
+ BE_GL_LoadLibrary(_this, NULL);
+#endif
+
+ /* Create the clear cursor */
+ SDL_BlankCursor = BE_CreateWMCursor(_this, blank_cdata, blank_cmask,
+ BLANK_CWIDTH, BLANK_CHEIGHT, BLANK_CHOTX, BLANK_CHOTY);
+
+ /* Fill in some window manager capabilities */
+ _this->info.wm_available = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+/* We support any dimension at our bit-depth */
+SDL_Rect **BE_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ SDL_Rect **modes;
+
+ modes = ((SDL_Rect **)0);
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1];
+ } else {
+ if ( format->BitsPerPixel ==
+ _this->screen->format->BitsPerPixel ) {
+ modes = ((SDL_Rect **)-1);
+ }
+ }
+ return(modes);
+}
+
+/* Various screen update functions available */
+static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+
+/* Find the closest display mode for fullscreen */
+static bool BE_FindClosestFSMode(_THIS, int width, int height, int bpp,
+ display_mode *mode)
+{
+ BScreen bscreen;
+ uint32 i, nmodes;
+ SDL_Rect **modes;
+ display_mode *dmodes;
+ display_mode current;
+ float current_refresh;
+ bscreen.GetMode(&current);
+ current_refresh = (1000 * current.timing.pixel_clock) /
+ (current.timing.h_total * current.timing.v_total);
+
+ modes = SDL_modelist[((bpp+7)/8)-1];
+
+ // find end of list (lowest-resolution mode; modes are ordered
+ // highest-to-lowest).
+ i = 0; while(modes[i]) i++;
+ if (!i) return false; // what? no modes at all?
+
+ // find first mode with resolution >= requested in both dimensions
+ for (--i; i >= 0; --i)
+ {
+ if (modes[i]->w >= width && modes[i]->h >= height)
+ break;
+ }
+
+ // unable to find any mode with that high a resolution!
+ if (i < 0)
+ return false;
+
+ width = modes[i]->w;
+ height = modes[i]->h;
+
+ bscreen.GetModeList(&dmodes, &nmodes);
+ for ( i = 0; i < nmodes; ++i ) {
+ if ( (bpp == ColorSpaceToBitsPerPixel(dmodes[i].space)) &&
+ (width == dmodes[i].virtual_width) &&
+ (height == dmodes[i].virtual_height) ) {
+ break;
+ }
+ }
+ if ( i != nmodes ) {
+ *mode = dmodes[i];
+ if ((mode->virtual_width <= current.virtual_width) &&
+ (mode->virtual_height <= current.virtual_height)) {
+ float new_refresh = (1000 * mode->timing.pixel_clock) /
+ (mode->timing.h_total * mode->timing.v_total);
+ if (new_refresh < current_refresh) {
+ mode->timing.pixel_clock = (uint32)((mode->timing.h_total * mode->timing.v_total)
+ * current_refresh / 1000);
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
+{
+ // printf("SetFullScreen(%d)\n", fullscreen);
+ BScreen bscreen;
+
+ // SetFullSscreen() does not work as expected if called in a window
+ // that was never shown. This is probably a bug in the Haiku Game Kit that needs
+ // to be investigated.
+ if (SDL_Win->Lock()) {
+ // Show our window.
+ SDL_Win->Show();
+ }
+
+ if (SDL_Win->IsLocked()) {
+ // Unlock the window if it was locked. This is needed as only the
+ // first call to Show() unlocks the looper. All other calls to it
+ // will not.
+ SDL_Win->Unlock();
+ }
+
+ int width = screen->w;
+ int height = screen->h;
+
+ if (fullscreen) {
+ // Set resolution to the closest available one that matches the
+ // current SDL resolution.
+ display_mode mode;
+ bscreen.GetMode(&mode);
+
+ int bpp = screen->format->BitsPerPixel;
+ if (bpp != ColorSpaceToBitsPerPixel(mode.space) ||
+ width != mode.virtual_width || height != mode.virtual_height) {
+ if(BE_FindClosestFSMode(_this, width, height, bpp, &mode)) {
+ bscreen.SetMode(&mode);
+ } else {
+ // printf("Could not set new mode.\n");
+ return(0);
+ }
+ }
+ } else {
+ // Reset to the previous known resolution as we are now in window
+ // mode.
+ bscreen.SetMode(&saved_mode);
+ }
+
+ // Effectivelly set/reset full screen mode. If we are already in
+ // full screen mode, we reset back to windowed mode first so the
+ // window can resize when going fullscreen.
+ // if (fullscreen)
+ // printf("Going fullscreen\n");
+ // else
+ // printf("Going windowed\n");
+ SDL_Win->SetFullScreen(fullscreen);
+
+ // Calculate offsets for centering the window (in window mode) and for
+ // dentering the bitmap (in full screen mode).
+ BRect bounds = bscreen.Frame();
+ bounds.PrintToStream();
+ int32 cx = (bounds.IntegerWidth() - width)/2;
+ int32 cy = (bounds.IntegerHeight() - height)/2;
+
+ // printf ("cx = %d, cy = %d\n", cx, cy);
+ if (!SDL_Win->IsFullScreen()) {
+ // printf("Doing not fullscreen stuff.\n");
+ // We are not in full screen mode, so we want to change the window
+ // size to match the resolution in SDL.
+ SDL_Win->ResizeTo(width, height);
+
+ // And also center the window and reset the drawing offset.
+ SDL_Win->MoveTo(cx, cy);
+ SDL_Win->SetXYOffset(0, 0);
+ } else {
+ // printf("Doing fullscreen stuff.");
+ // Center the bitmap whenever we are in full screen mode.
+ SDL_Win->SetXYOffset(cx, cy);
+ }
+
+ // Set relevant internal SDL screen flags.
+ if (SDL_Win->IsFullScreen()) {
+ screen->flags |= SDL_FULLSCREEN;
+ } else {
+ screen->flags &= ~SDL_FULLSCREEN;
+ }
+
+ return(1);
+}
+
+static int BE_ToggleFullScreen(_THIS, int fullscreen)
+{
+ return BE_SetFullScreen(_this, _this->screen, fullscreen);
+}
+
+/* FIXME: check return values and cleanup here */
+SDL_Surface *BE_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ BScreen bscreen;
+ BBitmap *bbitmap;
+ BRect bounds;
+ Uint32 gl_flags = 0;
+
+ /* Only RGB works on r5 currently */
+ gl_flags = BGL_RGB;
+ if (_this->gl_config.double_buffer)
+ gl_flags |= BGL_DOUBLE;
+ else
+ gl_flags |= BGL_SINGLE;
+ if (_this->gl_config.alpha_size > 0 || bpp == 32)
+ gl_flags |= BGL_ALPHA;
+ if (_this->gl_config.depth_size > 0)
+ gl_flags |= BGL_DEPTH;
+ if (_this->gl_config.stencil_size > 0)
+ gl_flags |= BGL_STENCIL;
+ if (_this->gl_config.accum_red_size > 0
+ || _this->gl_config.accum_green_size > 0
+ || _this->gl_config.accum_blue_size > 0
+ || _this->gl_config.accum_alpha_size > 0)
+ gl_flags |= BGL_ACCUM;
+
+ /* Create the view for this window, using found flags */
+ if ( SDL_Win->CreateView(flags, gl_flags) < 0 ) {
+ return(NULL);
+ }
+
+ current->flags = 0; /* Clear flags */
+ current->w = width;
+ current->h = height;
+ SDL_Win->SetType(B_TITLED_WINDOW);
+ if ( flags & SDL_NOFRAME ) {
+ current->flags |= SDL_NOFRAME;
+ SDL_Win->SetLook(B_NO_BORDER_WINDOW_LOOK);
+ } else {
+ if ( (flags & SDL_RESIZABLE) && !(flags & SDL_OPENGL) ) {
+ current->flags |= SDL_RESIZABLE;
+ /* We don't want opaque resizing (TM). :-) */
+ SDL_Win->SetFlags(B_OUTLINE_RESIZE);
+ } else {
+ SDL_Win->SetFlags(B_NOT_RESIZABLE|B_NOT_ZOOMABLE);
+ }
+ }
+
+ if ( flags & SDL_OPENGL ) {
+ current->flags |= SDL_OPENGL;
+ current->pitch = 0;
+ current->pixels = NULL;
+ _this->UpdateRects = NULL;
+ } else {
+ /* Create the BBitmap framebuffer */
+ bounds.top = 0; bounds.left = 0;
+ bounds.right = width-1;
+ bounds.bottom = height-1;
+ bbitmap = new BBitmap(bounds, bscreen.ColorSpace());
+ if ( ! bbitmap->IsValid() ) {
+ SDL_SetError("Couldn't create screen bitmap");
+ delete bbitmap;
+ return(NULL);
+ }
+ current->pitch = bbitmap->BytesPerRow();
+ current->pixels = (void *)bbitmap->Bits();
+ SDL_Win->SetBitmap(bbitmap);
+ _this->UpdateRects = BE_NormalUpdate;
+ }
+
+ /* Set the correct fullscreen mode */
+ BE_SetFullScreen(_this, current, flags & SDL_FULLSCREEN ? 1 : 0);
+
+ /* We're done */
+ return(current);
+}
+
+/* Update the current mouse state and position */
+void BE_UpdateMouse(_THIS)
+{
+ BPoint point;
+ uint32 buttons;
+
+ if ( SDL_Win->Lock() ) {
+ /* Get new input state, if still active */
+ if ( SDL_Win->IsActive() ) {
+ (SDL_Win->View())->GetMouse(&point, &buttons, true);
+ } else {
+ point.x = -1;
+ point.y = -1;
+ }
+ SDL_Win->Unlock();
+
+ if ( (point.x >= 0) && (point.x < SDL_VideoSurface->w) &&
+ (point.y >= 0) && (point.y < SDL_VideoSurface->h) ) {
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ SDL_PrivateMouseMotion(0, 0,
+ (Sint16)point.x, (Sint16)point.y);
+ } else {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+ }
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int BE_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void BE_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+static int BE_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+static void BE_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void BE_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ if ( SDL_Win->BeginDraw() ) {
+ int i;
+
+ for ( i=0; i<numrects; ++i ) {
+ BRect rect;
+
+ rect.top = rects[i].y;
+ rect.left = rects[i].x;
+ rect.bottom = rect.top+rects[i].h-1;
+ rect.right = rect.left+rects[i].w-1;
+ SDL_Win->DrawAsync(rect);
+ }
+ SDL_Win->EndDraw();
+ }
+}
+
+#if SDL_VIDEO_OPENGL
+/* Passing a NULL path means load pointers from the application */
+int BE_GL_LoadLibrary(_THIS, const char *path)
+{
+ if (path == NULL) {
+ if (_this->gl_config.dll_handle == NULL) {
+ image_info info;
+ int32 cookie = 0;
+ while (get_next_image_info(0,&cookie,&info) == B_OK) {
+ void *location = NULL;
+#ifdef __HAIKU__
+ if (get_image_symbol(info.id,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) { // This is how it actually works in Haiku
+#else
+ if (get_image_symbol((image_id)cookie,"glBegin",B_SYMBOL_TYPE_ANY,&location) == B_OK) { // I don't know if that *did* work in BeOS
+#endif
+ _this->gl_config.dll_handle = (void*)info.id;
+ _this->gl_config.driver_loaded = 1;
+ SDL_strlcpy(_this->gl_config.driver_path, "libGL.so", SDL_arraysize(_this->gl_config.driver_path));
+ }
+ }
+ }
+ } else {
+ /*
+ FIXME None of BeOS libGL.so implementations have exported functions
+ to load BGLView, which should be reloaded from new lib.
+ So for now just "load" linked libGL.so :(
+ */
+ if (_this->gl_config.dll_handle == NULL) {
+ return BE_GL_LoadLibrary(_this, NULL);
+ }
+
+ /* Unload old first */
+ /*if (_this->gl_config.dll_handle != NULL) {*/
+ /* Do not try to unload application itself (if LoadLibrary was called before with NULL ;) */
+ /* image_info info;
+ if (get_image_info((image_id)_this->gl_config.dll_handle, &info) == B_OK) {
+ if (info.type != B_APP_IMAGE) {
+ unload_add_on((image_id)_this->gl_config.dll_handle);
+ }
+ }
+
+ }
+
+ if ((_this->gl_config.dll_handle = (void*)load_add_on(path)) != (void*)B_ERROR) {
+ _this->gl_config.driver_loaded = 1;
+ SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path));
+ }*/
+ }
+
+ if (_this->gl_config.dll_handle != NULL) {
+ return 0;
+ } else {
+ _this->gl_config.dll_handle = NULL;
+ _this->gl_config.driver_loaded = 0;
+ *_this->gl_config.driver_path = '\0';
+ return -1;
+ }
+}
+
+void* BE_GL_GetProcAddress(_THIS, const char *proc)
+{
+ if (_this->gl_config.dll_handle != NULL) {
+ void *location = NULL;
+ status_t err;
+ if ((err = get_image_symbol((image_id)_this->gl_config.dll_handle, proc, B_SYMBOL_TYPE_ANY, &location)) == B_OK) {
+ return location;
+ } else {
+ SDL_SetError("Couldn't find OpenGL symbol");
+ return NULL;
+ }
+ } else {
+ SDL_SetError("OpenGL library not loaded");
+ return NULL;
+ }
+}
+
+int BE_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ /*
+ FIXME? Right now BE_GL_GetAttribute shouldn't be called between glBegin() and glEnd() - it doesn't use "cached" values
+ */
+ switch (attrib)
+ {
+ case SDL_GL_RED_SIZE:
+ glGetIntegerv(GL_RED_BITS, (GLint*)value);
+ break;
+ case SDL_GL_GREEN_SIZE:
+ glGetIntegerv(GL_GREEN_BITS, (GLint*)value);
+ break;
+ case SDL_GL_BLUE_SIZE:
+ glGetIntegerv(GL_BLUE_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ glGetIntegerv(GL_ALPHA_BITS, (GLint*)value);
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ glGetBooleanv(GL_DOUBLEBUFFER, (GLboolean*)value);
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ int v;
+ glGetIntegerv(GL_RED_BITS, (GLint*)&v);
+ *value = v;
+ glGetIntegerv(GL_GREEN_BITS, (GLint*)&v);
+ *value += v;
+ glGetIntegerv(GL_BLUE_BITS, (GLint*)&v);
+ *value += v;
+ glGetIntegerv(GL_ALPHA_BITS, (GLint*)&v);
+ *value += v;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ glGetIntegerv(GL_DEPTH_BITS, (GLint*)value); /* Mesa creates 16 only? r5 always 32 */
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ glGetIntegerv(GL_STENCIL_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ glGetIntegerv(GL_ACCUM_RED_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ glGetIntegerv(GL_ACCUM_GREEN_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ glGetIntegerv(GL_ACCUM_BLUE_BITS, (GLint*)value);
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ glGetIntegerv(GL_ACCUM_ALPHA_BITS, (GLint*)value);
+ break;
+ case SDL_GL_STEREO:
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ case SDL_GL_MULTISAMPLESAMPLES:
+ default:
+ *value=0;
+ return(-1);
+ }
+ return 0;
+}
+
+int BE_GL_MakeCurrent(_THIS)
+{
+ /* FIXME: should we glview->unlock and then glview->lock()? */
+ return 0;
+}
+
+void BE_GL_SwapBuffers(_THIS)
+{
+ SDL_Win->SwapBuffers();
+}
+#endif
+
+/* Is the system palette settable? */
+int BE_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ SDL_Palette *palette;
+ const color_map *cmap = BScreen().ColorMap();
+
+ /* Get the screen colormap */
+ palette = _this->screen->format->palette;
+ for ( i=0; i<256; ++i ) {
+ palette->colors[i].r = cmap->color_list[i].red;
+ palette->colors[i].g = cmap->color_list[i].green;
+ palette->colors[i].b = cmap->color_list[i].blue;
+ }
+ return(0);
+}
+
+void BE_VideoQuit(_THIS)
+{
+ int i, j;
+
+ SDL_Win->Quit();
+ SDL_Win = NULL;
+
+ if ( SDL_BlankCursor != NULL ) {
+ BE_FreeWMCursor(_this, SDL_BlankCursor);
+ SDL_BlankCursor = NULL;
+ }
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] ) {
+ for ( j=0; SDL_modelist[i][j]; ++j ) {
+ SDL_free(SDL_modelist[i][j]);
+ }
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+ /* Restore the original video mode */
+ if ( _this->screen ) {
+ if ( (_this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ BScreen bscreen;
+ bscreen.SetMode(&saved_mode);
+ }
+ _this->screen->pixels = NULL;
+ }
+
+#if SDL_VIDEO_OPENGL
+ if (_this->gl_config.dll_handle != NULL)
+ unload_add_on((image_id)_this->gl_config.dll_handle);
+#endif
+
+ SDL_QuitBeApp();
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm.cc
new file mode 100644
index 0000000..df80100
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm.cc
@@ -0,0 +1,92 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_BWin.h"
+
+extern "C" {
+#include "SDL_syswm_c.h"
+#include "SDL_error.h"
+#include "../SDL_cursor_c.h"
+
+void BE_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_Win->SetTitle(title);
+}
+
+int BE_IconifyWindow(_THIS)
+{
+ SDL_Win->Minimize(true);
+ return 1;
+}
+
+SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ if ( mode == SDL_GRAB_OFF ) {
+// be_app->ShowCursor();
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
+ /* BeSman: Jan 2, 2006
+ must be leaving relative mode, move mouse from
+ center of window to where it belongs ... */
+ BPoint pt;
+ int x, y;
+ SDL_GetMouseState(&x,&y);
+ pt.x = x;
+ pt.y = y;
+ SDL_Win->Lock();
+ SDL_Win->ConvertToScreen(&pt);
+ SDL_Win->Unlock();
+ set_mouse_position((int)pt.x, (int)pt.y);
+ }
+ } else {
+// be_app->HideCursor();
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
+ /* BeSman: Jan 2, 2006
+ must be entering relative mode, get ready by
+ moving mouse to center of window ... */
+ BPoint pt;
+ pt.x = (SDL_VideoSurface->w/2);
+ pt.y = (SDL_VideoSurface->h/2);
+ SDL_Win->Lock();
+ SDL_Win->ConvertToScreen(&pt);
+ SDL_Win->Unlock();
+ set_mouse_position((int)pt.x, (int)pt.y);
+ }
+ }
+ return(mode);
+}
+
+int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION)
+ {
+ return 1;
+ }
+ else
+ {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return -1;
+ }
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm_c.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm_c.h
new file mode 100644
index 0000000..c1285c8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_syswm_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_syswm.h"
+#include "SDL_lowvideo.h"
+
+
+/* Functions to be exported */
+extern void BE_SetWMCaption(_THIS, const char *title, const char *icon);
+extern int BE_IconifyWindow(_THIS);
+extern int BE_GetWMInfo(_THIS, SDL_SysWMinfo *info);
+extern SDL_GrabMode BE_GrabInput(_THIS, SDL_GrabMode mode);
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc
new file mode 100644
index 0000000..7c71b00
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.cc
@@ -0,0 +1,314 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the BeOS version of SDL YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_sysyuv.h"
+#include "../SDL_yuvfuncs.h"
+
+extern "C" {
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs be_yuvfuncs =
+{
+ BE_LockYUVOverlay,
+ BE_UnlockYUVOverlay,
+ BE_DisplayYUVOverlay,
+ BE_FreeYUVOverlay
+};
+
+BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs) {
+ BBitmap *bbitmap;
+ bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
+ if (!bbitmap || bbitmap->InitCheck() != B_OK) {
+ delete bbitmap;
+ return 0;
+ }
+ overlay_restrictions r;
+ bbitmap->GetOverlayRestrictions(&r);
+ uint32 width = bounds.IntegerWidth() + 1;
+ uint32 height = bounds.IntegerHeight() + 1;
+ uint32 width_padding = 0;
+ uint32 height_padding = 0;
+ if ((r.source.horizontal_alignment != 0) ||
+ (r.source.vertical_alignment != 0)) {
+ delete bbitmap;
+ return 0;
+ }
+ if (r.source.width_alignment != 0) {
+ uint32 aligned_width = r.source.width_alignment + 1;
+ if (width % aligned_width > 0) {
+ width_padding = aligned_width - width % aligned_width;
+ }
+ }
+ if (r.source.height_alignment != 0) {
+ uint32 aligned_height = r.source.height_alignment + 1;
+ if (height % aligned_height > 0) {
+ fprintf(stderr,"GetOverlayBitmap failed height alignment\n");
+ fprintf(stderr,"- height = %lu, aligned_height = %lu\n",height,aligned_height);
+ delete bbitmap;
+ return 0;
+ }
+ }
+ if ((r.source.min_width > width) ||
+ (r.source.min_height > height) ||
+ (r.source.max_width < width) ||
+ (r.source.max_height < height)) {
+ fprintf(stderr,"GetOverlayBitmap failed bounds tests\n");
+ delete bbitmap;
+ return 0;
+ }
+ if ((width_padding != 0) || (height_padding != 0)) {
+ delete bbitmap;
+ bounds.Set(bounds.left,bounds.top,bounds.right+width_padding,bounds.bottom+height_padding);
+ bbitmap = new BBitmap(bounds,B_BITMAP_WILL_OVERLAY,cs);
+ if (!bbitmap || bbitmap->InitCheck() != B_OK) {
+ fprintf(stderr,"GetOverlayBitmap failed late\n");
+ delete bbitmap;
+ return 0;
+ }
+ }
+ return bbitmap;
+}
+
+// See <GraphicsDefs.h> [btw: Cb=U, Cr=V]
+// See also http://www.fourcc.org/indexyuv.htm
+color_space convert_color_space(Uint32 format) {
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ return B_YUV9;
+ case SDL_IYUV_OVERLAY:
+ return B_YUV12;
+ case SDL_YUY2_OVERLAY:
+ return B_YCbCr422;
+ case SDL_UYVY_OVERLAY:
+ return B_YUV422;
+ case SDL_YVYU_OVERLAY: // not supported on beos?
+ return B_NO_COLOR_SPACE;
+ default:
+ return B_NO_COLOR_SPACE;
+ }
+}
+
+// See SDL_video.h
+int count_planes(Uint32 format) {
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ return 3;
+ case SDL_YUY2_OVERLAY:
+ case SDL_UYVY_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
+ SDL_Overlay* overlay;
+ struct private_yuvhwdata* hwdata;
+ BBitmap *bbitmap;
+ int planes;
+ BRect bounds;
+ color_space cs;
+
+ /* find the appropriate BeOS colorspace descriptor */
+ cs = convert_color_space(format);
+ if (cs == B_NO_COLOR_SPACE)
+ {
+ return NULL;
+ }
+
+ /* count planes */
+ planes = count_planes(format);
+ if (planes == 0)
+ {
+ return NULL;
+ }
+ /* TODO: figure out planar modes, if anyone cares */
+ if (planes == 3)
+ {
+ return NULL;
+ }
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay*)SDL_calloc(1, sizeof(SDL_Overlay));
+
+ if (overlay == NULL)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+ overlay->hwdata = NULL;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &be_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = (struct private_yuvhwdata*)SDL_calloc(1, sizeof(struct private_yuvhwdata));
+
+ if (hwdata == NULL)
+ {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+
+ overlay->hwdata = hwdata;
+ overlay->hwdata->display = display;
+ overlay->hwdata->bview = NULL;
+ overlay->hwdata->bbitmap = NULL;
+ overlay->hwdata->locked = 0;
+
+ /* Create the BBitmap framebuffer */
+ bounds.top = 0; bounds.left = 0;
+ bounds.right = width-1;
+ bounds.bottom = height-1;
+
+ BView * bview = new BView(bounds,"overlay",B_FOLLOW_NONE,B_WILL_DRAW);
+ if (!bview) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+ overlay->hwdata->bview = bview;
+ overlay->hwdata->first_display = true;
+ bview->Hide();
+
+ bbitmap = BE_GetOverlayBitmap(bounds,cs);
+ if (!bbitmap) {
+ overlay->hwdata->bbitmap = NULL;
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+ overlay->hwdata->bbitmap = bbitmap;
+
+ overlay->planes = planes;
+ overlay->pitches = (Uint16*)SDL_calloc(overlay->planes, sizeof(Uint16));
+ overlay->pixels = (Uint8**)SDL_calloc(overlay->planes, sizeof(Uint8*));
+ if (!overlay->pitches || !overlay->pixels)
+ {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+
+ overlay->pitches[0] = bbitmap->BytesPerRow();
+ overlay->pixels[0] = (Uint8 *)bbitmap->Bits();
+ overlay->hw_overlay = 1;
+
+ if (SDL_Win->LockWithTimeout(1000000) != B_OK) {
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ BView * view = SDL_Win->View();
+ view->AddChild(bview);
+ rgb_color key;
+ bview->SetViewOverlay(bbitmap,bounds,bview->Bounds(),&key,B_FOLLOW_ALL,
+ B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
+ bview->SetViewColor(key);
+ bview->Flush();
+ SDL_Win->Unlock();
+
+ current_overlay=overlay;
+
+ return overlay;
+}
+
+int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
+{
+ if (overlay == NULL)
+ {
+ return 0;
+ }
+
+ overlay->hwdata->locked = 1;
+ return 0;
+}
+
+void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
+{
+ if (overlay == NULL)
+ {
+ return;
+ }
+
+ overlay->hwdata->locked = 0;
+}
+
+int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect *dst)
+{
+ if ((overlay == NULL) || (overlay->hwdata==NULL)
+ || (overlay->hwdata->bview==NULL) || (SDL_Win->View() == NULL))
+ {
+ return -1;
+ }
+ if (SDL_Win->LockWithTimeout(50000) != B_OK) {
+ return 0;
+ }
+ BView * bview = overlay->hwdata->bview;
+ if (SDL_Win->IsFullScreen()) {
+ int left,top;
+ SDL_Win->GetXYOffset(left,top);
+ bview->MoveTo(left+dst->x,top+dst->y);
+ } else {
+ bview->MoveTo(dst->x,dst->y);
+ }
+ bview->ResizeTo(dst->w,dst->h);
+ bview->Flush();
+ if (overlay->hwdata->first_display) {
+ bview->Show();
+ overlay->hwdata->first_display = false;
+ }
+ SDL_Win->Unlock();
+
+ return 0;
+}
+
+void BE_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ if (overlay == NULL)
+ {
+ return;
+ }
+
+ if (overlay->hwdata == NULL)
+ {
+ return;
+ }
+
+ current_overlay=NULL;
+
+ delete overlay->hwdata->bbitmap;
+
+ SDL_free(overlay->hwdata);
+}
+
+}; // extern "C"
diff --git a/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.h b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.h
new file mode 100644
index 0000000..fb5961c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/bwindow/SDL_sysyuv.h
@@ -0,0 +1,73 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_SYS_YUV_H__
+#define __SDL_SYS_YUV_H__
+
+/* This is the BeOS implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_lowvideo.h"
+
+extern "C" {
+
+struct private_yuvhwdata
+{
+/* FRAMEDATA* CurrentFrameData;
+ FRAMEDATA* FrameData0;
+ FRAMEDATA* FrameData1;
+ PgScalerProps_t props;
+ PgScalerCaps_t caps;
+ PgVideoChannel_t* channel;
+ PhArea_t CurrentViewPort;
+ PhPoint_t CurrentWindowPos;
+ long format;
+ int scaler_on;
+ int current;
+ long YStride;
+ long VStride;
+ long UStride;
+ int ischromakey;
+ long chromakey;
+ int forcedredraw;
+ unsigned long State;
+ long flags;
+*/
+ SDL_Surface *display;
+ BView *bview;
+ bool first_display;
+ BBitmap *bbitmap;
+ int locked;
+};
+
+extern BBitmap * BE_GetOverlayBitmap(BRect bounds, color_space cs);
+extern SDL_Overlay* BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display);
+extern int BE_LockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern void BE_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern int BE_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect* dst);
+extern void BE_FreeYUVOverlay(_THIS, SDL_Overlay* overlay);
+
+};
+
+#endif /* __SDL_PH_YUV_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents.c b/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents.c
new file mode 100644
index 0000000..723b1dd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents.c
@@ -0,0 +1,101 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: libsdl-1.2.11-libcaca.patch,v 1.1 2006/09/18 16:06:06 mr_bones_ Exp $";
+#endif
+
+#include <stdio.h>
+
+#include <caca.h>
+#ifdef CACA_API_VERSION_1
+#include <caca0.h>
+#endif
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_cacavideo.h"
+#include "SDL_cacaevents_c.h"
+
+void Caca_PumpEvents(_THIS)
+{
+ int posted = 0;
+ int event;
+ SDL_keysym keysym;
+
+ if( ! this->screen ) /* Wait till we got the screen initialised */
+ return;
+
+ do {
+ posted = 0;
+
+ /* Get libcaca event */
+ SDL_mutexP(Caca_mutex);
+ event = caca_get_event(CACA_EVENT_ANY);
+ SDL_mutexV(Caca_mutex);
+
+ if ( event & (CACA_EVENT_KEY_PRESS | CACA_EVENT_KEY_RELEASE)) {
+ int key;
+ switch ( event & 0xffffff )
+ {
+ case CACA_KEY_LEFT: key = SDLK_LEFT; break;
+ case CACA_KEY_RIGHT: key = SDLK_RIGHT; break;
+ case CACA_KEY_UP: key = SDLK_UP; break;
+ case CACA_KEY_DOWN: key = SDLK_DOWN; break;
+ default: key = event & 0xff; break;
+ }
+ /* Key pressed */
+/* printf("Key pressed: %d (%c)\n", key, key); */
+ keysym.scancode = key;
+ keysym.sym = key;
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ if ( SDL_TranslateUNICODE ) {
+ keysym.unicode = key;
+ }
+ posted += SDL_PrivateKeyboard((event & CACA_EVENT_KEY_PRESS) ? SDL_PRESSED : SDL_RELEASED, &keysym);
+ }
+ else if ( event & (CACA_EVENT_MOUSE_PRESS | CACA_EVENT_MOUSE_RELEASE) ) {
+ /* FIXME: we currently ignore the button type! */
+ int button = event & 0x00ffffff;
+ if ( button > 3 ) {
+ button = 1;
+ }
+ posted += SDL_PrivateMouseButton((event & CACA_EVENT_MOUSE_PRESS) ? SDL_PRESSED : SDL_RELEASED, button, 0, 0);
+ }
+ else if ( event & CACA_EVENT_MOUSE_MOTION ) {
+ int new_x = 0, new_y = 0;
+ new_x = ((event & 0x00fff000) >> 12) * Caca_w / caca_get_width();
+ new_y = ((event & 0x00000fff) >> 0) * Caca_h / caca_get_height();
+ posted += SDL_PrivateMouseMotion(0, 0, new_x, new_y);
+ }
+ } while ( posted );
+}
+
+void Caca_InitOSKeymap(_THIS)
+{
+ return;
+}
+
+
diff --git a/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents_c.h b/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents_c.h
new file mode 100644
index 0000000..988c3b7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/caca/SDL_cacaevents_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: libsdl-1.2.11-libcaca.patch,v 1.1 2006/09/18 16:06:06 mr_bones_ Exp $";
+#endif
+
+#include "SDL_cacavideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts.
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void Caca_PumpEvents(_THIS);
+extern void Caca_InitOSKeymap(_THIS);
+
diff --git a/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.c b/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.c
new file mode 100644
index 0000000..59a070c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.c
@@ -0,0 +1,304 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2003 Sam Hocevar
+
+ 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 Hocevar
+ sam@zoy.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: libsdl-1.2.11-libcaca.patch,v 1.1 2006/09/18 16:06:06 mr_bones_ Exp $";
+#endif
+
+/* libcaca based SDL video driver implementation.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+#include "SDL.h"
+#include "SDL_error.h"
+#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_cacavideo.h"
+#include "SDL_cacaevents_c.h"
+
+#include <caca.h>
+#ifdef CACA_API_VERSION_1
+#include <caca0.h>
+#endif
+
+/* Initialization/Query functions */
+static int Caca_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **Caca_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *Caca_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static void Caca_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int Caca_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int Caca_LockHWSurface(_THIS, SDL_Surface *surface);
+static int Caca_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void Caca_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void Caca_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Cache the VideoDevice struct */
+static struct SDL_VideoDevice *local_this;
+
+/* libcaca driver bootstrap functions */
+
+static int Caca_Available(void)
+{
+ return 1; /* Always available ! */
+}
+
+static void Caca_DeleteDevice(SDL_VideoDevice *device)
+{
+ free(device->hidden);
+ free(device);
+}
+static SDL_VideoDevice *Caca_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ free(device);
+ }
+ return(0);
+ }
+ memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = Caca_VideoInit;
+ device->ListModes = Caca_ListModes;
+ device->SetVideoMode = Caca_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = NULL;
+ device->UpdateRects = NULL;
+ device->VideoQuit = Caca_VideoQuit;
+ device->AllocHWSurface = Caca_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = Caca_LockHWSurface;
+ device->UnlockHWSurface = Caca_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = Caca_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = Caca_InitOSKeymap;
+ device->PumpEvents = Caca_PumpEvents;
+
+ device->free = Caca_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap CACA_bootstrap = {
+ "caca", "Color ASCII Art Library",
+ Caca_Available, Caca_CreateDevice
+};
+
+int Caca_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i;
+
+ /* Initialize all variables that we clean on shutdown */
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ SDL_modelist[i] = malloc(sizeof(SDL_Rect));
+ SDL_modelist[i]->x = SDL_modelist[i]->y = 0;
+ }
+ /* Modes sorted largest to smallest */
+ SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768;
+ SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600;
+ SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480;
+ SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400;
+ SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240;
+ SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200;
+ SDL_modelist[6] = NULL;
+
+ Caca_mutex = SDL_CreateMutex();
+
+ /* Initialize the library */
+ if ( caca_init() != 0 ) {
+ SDL_SetError("Unable to initialize libcaca");
+ return(-1);
+ }
+
+ /* Initialize private variables */
+ Caca_lastkey = 0;
+ Caca_bitmap = NULL;
+ Caca_buffer = NULL;
+
+ local_this = this;
+
+ /* Determine the screen depth (use default 8-bit depth) */
+ vformat->BitsPerPixel = 8;
+ vformat->BytesPerPixel = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **Caca_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if(format->BitsPerPixel != 8)
+ return NULL;
+
+ if ( flags & SDL_FULLSCREEN ) {
+ return SDL_modelist;
+ } else {
+ return (SDL_Rect **) -1;
+ }
+}
+
+/* Various screen update functions available */
+static void Caca_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *Caca_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if ( Caca_buffer ) {
+ free( Caca_buffer );
+ Caca_buffer = NULL;
+ }
+
+ if ( Caca_bitmap ) {
+ caca_free_bitmap( Caca_bitmap );
+ Caca_bitmap = NULL;
+ }
+
+ Caca_buffer = malloc(2 * ((width + 15) & ~15) * height);
+ if ( ! Caca_buffer ) {
+ SDL_SetError("Couldn't allocate buffer for requested mode");
+ return(NULL);
+ }
+
+ memset(Caca_buffer, 0, 2 * ((width + 15) & ~15) * height);
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, 16, 0xf800, 0x07e0, 0x001f, 0) ) {
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = SDL_FULLSCREEN;
+ Caca_w = current->w = width;
+ Caca_h = current->h = height;
+ current->pitch = 2 * ((width + 15) & ~15);
+ current->pixels = Caca_buffer;
+
+ /* Create the libcaca bitmap */
+ Caca_bitmap = caca_create_bitmap( 16, width, height, current->pitch, 0xf800, 0x07e0, 0x001f, 0x0000 );
+ if ( ! Caca_bitmap ) {
+ SDL_SetError("Couldn't allocate libcaca bitmap");
+ return(NULL);
+ }
+
+ /* Set the blit function */
+ this->UpdateRects = Caca_DirectUpdate;
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int Caca_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void Caca_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int Caca_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ /* TODO ? */
+ return(0);
+}
+static void Caca_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* FIXME: How is this done with libcaca? */
+static int Caca_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ SDL_mutexP(Caca_mutex);
+ caca_refresh();
+ SDL_mutexV(Caca_mutex);
+ return(0);
+}
+
+static void Caca_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ SDL_mutexP(Caca_mutex);
+ caca_draw_bitmap( 0, 0, caca_get_width() - 1, caca_get_height() - 1,
+ Caca_bitmap, Caca_buffer );
+ caca_refresh();
+ SDL_mutexV(Caca_mutex);
+ return;
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void Caca_VideoQuit(_THIS)
+{
+ int i;
+
+ /* Free video mode lists */
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ if ( Caca_bitmap ) {
+ caca_free_bitmap( Caca_bitmap );
+ Caca_bitmap = NULL;
+ }
+
+ caca_end();
+
+ SDL_DestroyMutex(Caca_mutex);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.h b/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.h
new file mode 100644
index 0000000..91fcc81
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/caca/SDL_cacavideo.h
@@ -0,0 +1,76 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2003 Sam Hocevar
+
+ 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 Hocevar
+ sam@zoy.org
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: libsdl-1.2.11-libcaca.patch,v 1.1 2006/09/18 16:06:06 mr_bones_ Exp $";
+#endif
+
+#ifndef _SDL_cacavideo_h
+#define _SDL_cacavideo_h
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_mutex.h"
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <caca.h>
+#ifdef CACA_API_VERSION_1
+#include <caca0.h>
+#endif
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define SDL_NUMMODES 6
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ SDL_Rect *SDL_modelist[SDL_NUMMODES+1];
+ SDL_mutex *mutex;
+
+ struct caca_bitmap *bitmap;
+ void *buffer;
+ int w, h;
+
+ int lastkey;
+ struct timeval lasttime;
+};
+
+/* Old variable names */
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define Caca_palette (this->hidden->palette)
+#define Caca_bitmap (this->hidden->bitmap)
+#define Caca_buffer (this->hidden->buffer)
+
+#define Caca_w (this->hidden->w)
+#define Caca_h (this->hidden->h)
+
+#define Caca_lastkey (this->hidden->lastkey)
+#define Caca_lasttime (this->hidden->lasttime)
+
+#define Caca_mutex (this->hidden->mutex)
+
+#endif /* _SDL_cacavideo_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents.c b/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents.c
new file mode 100644
index 0000000..38dcca4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents.c
@@ -0,0 +1,152 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_dcvideo.h"
+#include "SDL_dcevents_c.h"
+
+#include <dc/maple.h>
+#include <dc/maple/mouse.h>
+#include <dc/maple/keyboard.h>
+
+const static unsigned short sdl_key[]= {
+ /*0*/ 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z',
+ /*1e*/ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ /*28*/ SDLK_RETURN, SDLK_ESCAPE, SDLK_BACKSPACE, SDLK_TAB, SDLK_SPACE, SDLK_MINUS, SDLK_PLUS, SDLK_LEFTBRACKET,
+ SDLK_RIGHTBRACKET, SDLK_BACKSLASH , 0, SDLK_SEMICOLON, SDLK_QUOTE,
+ /*35*/ '~', SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_CAPSLOCK,
+ SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_F11, SDLK_F12,
+ /*46*/ SDLK_PRINT, SDLK_SCROLLOCK, SDLK_PAUSE, SDLK_INSERT, SDLK_HOME, SDLK_PAGEUP, SDLK_DELETE, SDLK_END, SDLK_PAGEDOWN, SDLK_RIGHT, SDLK_LEFT, SDLK_DOWN, SDLK_UP,
+ /*53*/ SDLK_NUMLOCK, SDLK_KP_DIVIDE, SDLK_KP_MULTIPLY, SDLK_KP_MINUS, SDLK_KP_PLUS, SDLK_KP_ENTER,
+ SDLK_KP1, SDLK_KP2, SDLK_KP3, SDLK_KP4, SDLK_KP5, SDLK_KP6,
+ /*5f*/ SDLK_KP7, SDLK_KP8, SDLK_KP9, SDLK_KP0, SDLK_KP_PERIOD, 0 /* S3 */
+};
+
+const static unsigned short sdl_shift[] = {
+ SDLK_LCTRL,SDLK_LSHIFT,SDLK_LALT,0 /* S1 */,
+ SDLK_RCTRL,SDLK_RSHIFT,SDLK_RALT,0 /* S2 */,
+};
+
+#define MOUSE_WHEELUP (1<<4)
+#define MOUSE_WHEELDOWN (1<<5)
+
+static void mouse_update(void)
+{
+const static char sdl_mousebtn[] = {
+ MOUSE_LEFTBUTTON,
+ MOUSE_RIGHTBUTTON,
+ MOUSE_SIDEBUTTON,
+ MOUSE_WHEELUP,
+ MOUSE_WHEELDOWN
+};
+
+ uint8 addr;
+ mouse_cond_t cond;
+
+ static int prev_buttons;
+ int buttons,changed;
+ int i;
+
+ if ((addr = maple_first_mouse())==0 || mouse_get_cond(addr, &cond)<0) return;
+
+ buttons = cond.buttons^0xff;
+ if (cond.dz<0) buttons|=MOUSE_WHEELUP;
+ if (cond.dz>0) buttons|=MOUSE_WHEELDOWN;
+
+ if (cond.dx||cond.dy) SDL_PrivateMouseMotion(0,1,cond.dx,cond.dy);
+
+ changed = buttons^prev_buttons;
+ for(i=0;i<sizeof(sdl_mousebtn);i++) {
+ if (changed & sdl_mousebtn[i]) {
+ SDL_PrivateMouseButton((buttons & sdl_mousebtn[i])?SDL_PRESSED:SDL_RELEASED,i,0,0);
+ }
+ }
+ prev_buttons = buttons;
+}
+
+static void keyboard_update(void)
+{
+ static kbd_state_t old_state;
+ static uint8 old_addr;
+
+ kbd_state_t *state;
+ uint8 addr;
+ int port,unit;
+
+ int shiftkeys;
+ SDL_keysym keysym;
+
+ int i;
+
+ addr = maple_first_kb();
+
+ if (addr==0) return;
+
+ if (addr!=old_addr) {
+ old_addr = addr;
+ SDL_memset(&old_state,0,sizeof(old_state));
+ }
+
+ maple_raddr(addr,&port,&unit);
+
+ state = maple_dev_state(port,unit);
+ if (!state) return;
+
+ shiftkeys = state->shift_keys ^ old_state.shift_keys;
+ for(i=0;i<sizeof(sdl_shift);i++) {
+ if ((shiftkeys>>i)&1) {
+ keysym.sym = sdl_shift[i];
+ SDL_PrivateKeyboard(((state->shift_keys>>i)&1)?SDL_PRESSED:SDL_RELEASED,&keysym);
+ }
+ }
+
+ for(i=0;i<sizeof(sdl_key);i++) {
+ if (state->matrix[i]!=old_state.matrix[i]) {
+ int key = sdl_key[i];
+ if (key) {
+ keysym.sym = key;
+ SDL_PrivateKeyboard(state->matrix[i]?SDL_PRESSED:SDL_RELEASED,&keysym);
+ }
+ }
+ }
+
+ old_state = *state;
+}
+
+void DC_PumpEvents(_THIS)
+{
+ keyboard_update();
+ mouse_update();
+}
+
+void DC_InitOSKeymap(_THIS)
+{
+ /* do nothing. */
+}
+
+/* end of SDL_dcevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents_c.h b/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents_c.h
new file mode 100644
index 0000000..3196eae
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcevents_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_dcvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void DC_InitOSKeymap(_THIS);
+extern void DC_PumpEvents(_THIS);
+
+/* end of SDL_dcevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse.c b/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse.c
new file mode 100644
index 0000000..61a0ba0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse.c
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <stdio.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_dcmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse_c.h b/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse_c.h
new file mode 100644
index 0000000..dc018bb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcmouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_dcvideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.c b/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.c
new file mode 100644
index 0000000..5838a49
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.c
@@ -0,0 +1,445 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#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_dcvideo.h"
+#include "SDL_dcevents_c.h"
+#include "SDL_dcmouse_c.h"
+
+#include <dc/video.h>
+#include <dc/pvr.h>
+
+
+/* Initialization/Query functions */
+static int DC_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void DC_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DC_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DC_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DC_FreeHWSurface(_THIS, SDL_Surface *surface);
+static int DC_FlipHWSurface(_THIS, SDL_Surface *surface);
+
+/* etc. */
+static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+/* OpenGL */
+#if SDL_VIDEO_OPENGL
+static void *DC_GL_GetProcAddress(_THIS, const char *proc);
+static int DC_GL_LoadLibrary(_THIS, const char *path);
+static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+static void DC_GL_SwapBuffers(_THIS);
+#endif
+
+/* DC driver bootstrap functions */
+
+static int DC_Available(void)
+{
+ return 1;
+}
+
+static void DC_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *DC_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = DC_VideoInit;
+ device->ListModes = DC_ListModes;
+ device->SetVideoMode = DC_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = DC_SetColors;
+ device->UpdateRects = DC_UpdateRects;
+ device->VideoQuit = DC_VideoQuit;
+ device->AllocHWSurface = DC_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = DC_LockHWSurface;
+ device->UnlockHWSurface = DC_UnlockHWSurface;
+ device->FlipHWSurface = DC_FlipHWSurface;
+ device->FreeHWSurface = DC_FreeHWSurface;
+#if SDL_VIDEO_OPENGL
+ device->GL_LoadLibrary = DC_GL_LoadLibrary;
+ device->GL_GetProcAddress = DC_GL_GetProcAddress;
+ device->GL_GetAttribute = DC_GL_GetAttribute;
+ device->GL_MakeCurrent = NULL;
+ device->GL_SwapBuffers = DC_GL_SwapBuffers;
+#endif
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = DC_InitOSKeymap;
+ device->PumpEvents = DC_PumpEvents;
+
+ device->free = DC_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap DC_bootstrap = {
+ "dcvideo", "Dreamcast Video",
+ DC_Available, DC_CreateDevice
+};
+
+
+int DC_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ /* Determine the screen depth (use default 16-bit depth) */
+ /* we change this during the SDL_SetVideoMode implementation... */
+ vformat->BitsPerPixel = 16;
+ vformat->Rmask = 0x0000f800;
+ vformat->Gmask = 0x000007e0;
+ vformat->Bmask = 0x0000001f;
+
+ /* We're done! */
+ return(0);
+}
+
+const static SDL_Rect
+ RECT_800x600 = {0,0,800,600},
+ RECT_640x480 = {0,0,640,480},
+ RECT_320x240 = {0,0,320,240};
+const static SDL_Rect *vid_modes[] = {
+ &RECT_800x600,
+ &RECT_640x480,
+ &RECT_320x240,
+ NULL
+};
+
+SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ switch(format->BitsPerPixel) {
+ case 15:
+ case 16:
+ return &vid_modes;
+ case 32:
+ if (!(flags & SDL_OPENGL))
+ return &vid_modes;
+ default:
+ return NULL;
+ }
+// return (SDL_Rect **) -1;
+}
+
+pvr_init_params_t params = {
+ /* Enable opaque and translucent polygons with size 16 */
+ { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16 },
+
+ /* Vertex buffer size */
+ 512*1024
+};
+
+#if SDL_VIDEO_OPENGL
+static int pvr_inited;
+#endif
+
+SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ int disp_mode,pixel_mode,pitch;
+ Uint32 Rmask, Gmask, Bmask;
+
+ if (width==320 && height==240) disp_mode=DM_320x240;
+ else if (width==640 && height==480) disp_mode=DM_640x480;
+ else if (width==800 && height==600) disp_mode=DM_800x608;
+ else {
+ SDL_SetError("Couldn't find requested mode in list");
+ return(NULL);
+ }
+
+ switch(bpp) {
+ case 15: pixel_mode = PM_RGB555; pitch = width*2;
+ /* 5-5-5 */
+ Rmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Bmask = 0x0000001f;
+ break;
+ case 16: pixel_mode = PM_RGB565; pitch = width*2;
+ /* 5-6-5 */
+ Rmask = 0x0000f800;
+ Gmask = 0x000007e0;
+ Bmask = 0x0000001f;
+ break;
+ case 24: bpp = 32;
+ case 32: pixel_mode = PM_RGB888; pitch = width*4;
+ Rmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Bmask = 0x000000ff;
+#if SDL_VIDEO_OPENGL
+ if (!(flags & SDL_OPENGL))
+#endif
+ break;
+ default:
+ SDL_SetError("Couldn't find requested mode in list");
+ return(NULL);
+ }
+
+// if ( bpp != current->format->BitsPerPixel ) {
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
+ return(NULL);
+ }
+// }
+
+ /* Set up the new mode framebuffer */
+ current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
+ current->w = width;
+ current->h = height;
+ current->pitch = pitch;
+
+#if SDL_VIDEO_OPENGL
+ if (pvr_inited) {
+ pvr_inited = 0;
+ pvr_shutdown();
+ }
+#endif
+
+ vid_set_mode(disp_mode,pixel_mode);
+
+ current->pixels = vram_s;
+
+#if SDL_VIDEO_OPENGL
+ if (flags & SDL_OPENGL) {
+ this->gl_config.driver_loaded = 1;
+ current->flags = SDL_FULLSCREEN | SDL_OPENGL;
+ current->pixels = NULL;
+ pvr_inited = 1;
+ pvr_init(&params);
+ glKosInit();
+ glKosBeginFrame();
+ } else
+#endif
+ if (flags | SDL_DOUBLEBUF) {
+ current->flags |= SDL_DOUBLEBUF;
+ current->pixels = (void*)((int)current->pixels | 0x400000);
+ }
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int DC_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void DC_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int DC_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int DC_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (surface->flags & SDL_DOUBLEBUF) {
+ vid_set_start((int)surface->pixels & 0xffffff);
+ surface->pixels = (void*)((int)surface->pixels ^ 0x400000);
+ }
+ return(0);
+}
+
+static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ /* do nothing. */
+}
+
+static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ /* do nothing of note. */
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+static void DC_VideoQuit(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ if (pvr_inited) {
+ pvr_inited = 0;
+ pvr_shutdown();
+ }
+#endif
+}
+
+#if SDL_VIDEO_OPENGL
+
+void dmyfunc(void) {}
+
+typedef void (*funcptr)();
+const static struct {
+ char *name;
+ funcptr addr;
+} glfuncs[] = {
+#define DEF(func) {#func,&func}
+ DEF(glBegin),
+ DEF(glBindTexture),
+ DEF(glBlendFunc),
+ DEF(glColor4f),
+// DEF(glCopyImageID),
+ DEF(glDisable),
+ DEF(glEnable),
+ DEF(glEnd),
+ DEF(glFlush),
+ DEF(glGenTextures),
+ DEF(glGetString),
+ DEF(glLoadIdentity),
+ DEF(glMatrixMode),
+ DEF(glOrtho),
+ DEF(glPixelStorei),
+// DEF(glPopAttrib),
+// DEF(glPopClientAttrib),
+ {"glPopAttrib",&dmyfunc},
+ {"glPopClientAttrib",&dmyfunc},
+ DEF(glPopMatrix),
+// DEF(glPushAttrib),
+// DEF(glPushClientAttrib),
+ {"glPushAttrib",&dmyfunc},
+ {"glPushClientAttrib",&dmyfunc},
+ DEF(glPushMatrix),
+ DEF(glTexCoord2f),
+ DEF(glTexEnvf),
+ DEF(glTexImage2D),
+ DEF(glTexParameteri),
+ DEF(glTexSubImage2D),
+ DEF(glVertex2i),
+ DEF(glViewport),
+#undef DEF
+};
+
+static void *DC_GL_GetProcAddress(_THIS, const char *proc)
+{
+ void *ret;
+ int i;
+
+ ret = glKosGetProcAddress(proc);
+ if (ret) return ret;
+
+ for(i=0;i<sizeof(glfuncs)/sizeof(glfuncs[0]);i++) {
+ if (SDL_strcmp(proc,glfuncs[i].name)==0) return glfuncs[i].addr;
+ }
+
+ return NULL;
+}
+
+static int DC_GL_LoadLibrary(_THIS, const char *path)
+{
+ this->gl_config.driver_loaded = 1;
+
+ return 0;
+}
+
+static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ GLenum mesa_attrib;
+ int val;
+
+ switch(attrib) {
+ case SDL_GL_RED_SIZE:
+ val = 5;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ val = 6;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ val = 5;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ val = 0;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ val = 1;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ val = 16; /* or 32? */
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ val = 0;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ val = 0;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ val = 0;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ val = 0;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ val = 0;
+ break;
+ default :
+ return -1;
+ }
+ *value = val;
+ return 0;
+}
+
+static void DC_GL_SwapBuffers(_THIS)
+{
+ glKosFinishFrame();
+ glKosBeginFrame();
+}
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.h b/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.h
new file mode 100644
index 0000000..837f028
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dc/SDL_dcvideo.h
@@ -0,0 +1,42 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_dcvideo_h
+#define _SDL_dcvideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ int w, h;
+ void *buffer;
+};
+
+#endif /* _SDL_dcvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/default_cursor.h b/distrib/sdl-1.2.15/src/video/default_cursor.h
new file mode 100644
index 0000000..d637223
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/default_cursor.h
@@ -0,0 +1,116 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Default cursor - it happens to be the Mac cursor, but could be anything */
+
+#define DEFAULT_CWIDTH 16
+#define DEFAULT_CHEIGHT 16
+#define DEFAULT_CHOTX 0
+#define DEFAULT_CHOTY 0
+
+/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrière */
+#define USE_MACOS_CURSOR
+
+#ifdef USE_MACOS_CURSOR
+
+static unsigned char default_cdata[] =
+{
+ 0x00,0x00,
+ 0x40,0x00,
+ 0x60,0x00,
+ 0x70,0x00,
+ 0x78,0x00,
+ 0x7C,0x00,
+ 0x7E,0x00,
+ 0x7F,0x00,
+ 0x7F,0x80,
+ 0x7C,0x00,
+ 0x6C,0x00,
+ 0x46,0x00,
+ 0x06,0x00,
+ 0x03,0x00,
+ 0x03,0x00,
+ 0x00,0x00
+};
+static unsigned char default_cmask[] =
+{
+ 0xC0,0x00,
+ 0xE0,0x00,
+ 0xF0,0x00,
+ 0xF8,0x00,
+ 0xFC,0x00,
+ 0xFE,0x00,
+ 0xFF,0x00,
+ 0xFF,0x80,
+ 0xFF,0xC0,
+ 0xFF,0xE0,
+ 0xFE,0x00,
+ 0xEF,0x00,
+ 0xCF,0x00,
+ 0x87,0x80,
+ 0x07,0x80,
+ 0x03,0x00
+};
+
+#else
+
+static unsigned char default_cdata[] =
+{
+ 0x00,0x00,
+ 0x40,0x00,
+ 0x60,0x00,
+ 0x70,0x00,
+ 0x78,0x00,
+ 0x7C,0x00,
+ 0x7E,0x00,
+ 0x7F,0x00,
+ 0x7F,0x80,
+ 0x7C,0x00,
+ 0x6C,0x00,
+ 0x46,0x00,
+ 0x06,0x00,
+ 0x03,0x00,
+ 0x03,0x00,
+ 0x00,0x00
+};
+static unsigned char default_cmask[] =
+{
+ 0x40,0x00,
+ 0xE0,0x00,
+ 0xF0,0x00,
+ 0xF8,0x00,
+ 0xFC,0x00,
+ 0xFE,0x00,
+ 0xFF,0x00,
+ 0xFF,0x80,
+ 0xFF,0xC0,
+ 0xFF,0x80,
+ 0xFE,0x00,
+ 0xEF,0x00,
+ 0x4F,0x00,
+ 0x07,0x80,
+ 0x07,0x80,
+ 0x03,0x00
+};
+
+#endif /* TRUE_MACINTOSH_CURSOR */
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents.c b/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents.c
new file mode 100644
index 0000000..4e6d5f0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents.c
@@ -0,0 +1,163 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting DGA events into SDL events */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "../Xext/extensions/xf86dga.h"
+
+#include "SDL_timer.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_dgavideo.h"
+#include "SDL_dgaevents_c.h"
+
+/* get function pointers... */
+#include "../x11/SDL_x11dyn.h"
+
+/* Heheh we're using X11 event code */
+extern int X11_Pending(Display *display);
+extern void X11_InitKeymap(void);
+extern SDLKey X11_TranslateKeycode(Display *display, KeyCode kc);
+
+static int DGA_DispatchEvent(_THIS)
+{
+ int posted;
+ SDL_NAME(XDGAEvent) xevent;
+
+ XNextEvent(DGA_Display, (XEvent *)&xevent);
+
+ posted = 0;
+ xevent.type -= DGA_event_base;
+ switch (xevent.type) {
+
+ /* Mouse motion? */
+ case MotionNotify: {
+ if ( SDL_VideoSurface ) {
+ posted = SDL_PrivateMouseMotion(0, 1,
+ xevent.xmotion.dx, xevent.xmotion.dy);
+ }
+ }
+ break;
+
+ /* Mouse button press? */
+ case ButtonPress: {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED,
+ xevent.xbutton.button, 0, 0);
+ }
+ break;
+
+ /* Mouse button release? */
+ case ButtonRelease: {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED,
+ xevent.xbutton.button, 0, 0);
+ }
+ break;
+
+ /* Key press? */
+ case KeyPress: {
+ SDL_keysym keysym;
+ KeyCode keycode;
+ XKeyEvent xkey;
+
+ SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey);
+ keycode = xkey.keycode;
+#ifdef DEBUG_XEVENTS
+printf("KeyPress (X11 keycode = 0x%X)\n", xkey.keycode);
+#endif
+ /* Get the translated SDL virtual keysym */
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(DGA_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+
+ /* Look up the translated value for the key event */
+ if ( SDL_TranslateUNICODE ) {
+ static XComposeStatus state;
+ char keybuf[32];
+
+ if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, &state) ) {
+ /*
+ * FIXME: XLookupString() may yield more than one
+ * character, so we need a mechanism to allow for
+ * this (perhaps null keypress events with a
+ * unicode value)
+ */
+ keysym.unicode = (Uint8)keybuf[0];
+ }
+ }
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ break;
+
+ /* Key release? */
+ case KeyRelease: {
+ SDL_keysym keysym;
+ KeyCode keycode;
+ XKeyEvent xkey;
+
+ SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey);
+ keycode = xkey.keycode;
+#ifdef DEBUG_XEVENTS
+printf("KeyRelease (X11 keycode = 0x%X)\n", xkey.keycode);
+#endif
+ /* Get the translated SDL virtual keysym */
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(DGA_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+ }
+ break;
+ }
+ return(posted);
+}
+
+void DGA_PumpEvents(_THIS)
+{
+ /* Keep processing pending events */
+ LOCK_DISPLAY();
+
+ /* Update activity every five seconds to prevent screensaver. --ryan. */
+ if (!allow_screensaver) {
+ static Uint32 screensaverTicks;
+ Uint32 nowTicks = SDL_GetTicks();
+ if ((nowTicks - screensaverTicks) > 5000) {
+ XResetScreenSaver(DGA_Display);
+ screensaverTicks = nowTicks;
+ }
+ }
+
+ while ( X11_Pending(DGA_Display) ) {
+ DGA_DispatchEvent(this);
+ }
+
+ UNLOCK_DISPLAY();
+}
+
+void DGA_InitOSKeymap(_THIS)
+{
+ X11_InitKeymap();
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents_c.h b/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents_c.h
new file mode 100644
index 0000000..45f8cc5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgaevents_c.h
@@ -0,0 +1,28 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_dgavideo.h"
+
+/* Functions to be exported */
+extern void DGA_PumpEvents(_THIS);
+extern void DGA_InitOSKeymap(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse.c b/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse.c
new file mode 100644
index 0000000..43bc5d6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse.c
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <stdio.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_dgavideo.h"
+#include "SDL_dgamouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse_c.h b/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse_c.h
new file mode 100644
index 0000000..4ea8b21
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgamouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_dgavideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.c b/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.c
new file mode 100644
index 0000000..267d5cc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.c
@@ -0,0 +1,1101 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* DGA 2.0 based SDL video driver implementation.
+*/
+
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include "../Xext/extensions/xf86dga.h"
+
+#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_dgavideo.h"
+#include "SDL_dgamouse_c.h"
+#include "SDL_dgaevents_c.h"
+
+/* get function pointers... */
+#include "../x11/SDL_x11dyn.h"
+
+/*#define DGA_DEBUG*/
+
+/* Initialization/Query functions */
+static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DGA_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static int DGA_SetGammaRamp(_THIS, Uint16 *ramp);
+static void DGA_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size);
+static void DGA_FreeHWSurfaces(_THIS);
+static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
+static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
+static int DGA_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface);
+static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface);
+
+/* DGA driver bootstrap functions */
+
+static int DGA_Available(void)
+{
+ const char *display = NULL;
+ Display *dpy = NULL;
+ int available = 0;
+
+ /* The driver is available is available if the display is local
+ and the DGA 2.0+ extension is available, and we can map mem.
+ */
+ if ( SDL_X11_LoadSymbols() ) {
+ if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
+ (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) {
+ dpy = XOpenDisplay(display);
+ if ( dpy ) {
+ int events, errors, major, minor;
+
+ if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) &&
+ SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) {
+ int screen;
+
+ screen = DefaultScreen(dpy);
+ if ( (major >= 2) &&
+ SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) {
+ available = 1;
+ SDL_NAME(XDGACloseFramebuffer)(dpy, screen);
+ }
+ }
+ XCloseDisplay(dpy);
+ }
+ }
+ SDL_X11_UnloadSymbols();
+ }
+ return(available);
+}
+
+static void DGA_DeleteDevice(SDL_VideoDevice *device)
+{
+ if (device != NULL) {
+ SDL_free(device->hidden);
+ SDL_free(device);
+ SDL_X11_UnloadSymbols();
+ }
+}
+
+static SDL_VideoDevice *DGA_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device = NULL;
+
+ /* Initialize all variables that we clean on shutdown */
+ if (SDL_X11_LoadSymbols()) {
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ SDL_X11_UnloadSymbols();
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = DGA_VideoInit;
+ device->ListModes = DGA_ListModes;
+ device->SetVideoMode = DGA_SetVideoMode;
+ device->SetColors = DGA_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = DGA_VideoQuit;
+ device->AllocHWSurface = DGA_AllocHWSurface;
+ device->CheckHWBlit = DGA_CheckHWBlit;
+ device->FillHWRect = DGA_FillHWRect;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = DGA_LockHWSurface;
+ device->UnlockHWSurface = DGA_UnlockHWSurface;
+ device->FlipHWSurface = DGA_FlipHWSurface;
+ device->FreeHWSurface = DGA_FreeHWSurface;
+ device->SetGammaRamp = DGA_SetGammaRamp;
+ device->GetGammaRamp = NULL;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = DGA_InitOSKeymap;
+ device->PumpEvents = DGA_PumpEvents;
+
+ device->free = DGA_DeleteDevice;
+ }
+
+ return device;
+}
+
+VideoBootStrap DGA_bootstrap = {
+ "dga", "XFree86 DGA 2.0",
+ DGA_Available, DGA_CreateDevice
+};
+
+static int DGA_AddMode(_THIS, int bpp, int w, int h)
+{
+ SDL_Rect *mode;
+ int index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( bpp < 8 ) { /* Not supported */
+ return(0);
+ }
+ index = ((bpp+7)/8)-1;
+ if ( SDL_nummodes[index] > 0 ) {
+ mode = SDL_modelist[index][SDL_nummodes[index]-1];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+/* This whole function is a hack. :) */
+static Uint32 get_video_size(_THIS)
+{
+ /* This is a non-exported function from libXxf86dga.a */
+ extern unsigned char *SDL_NAME(XDGAGetMappedMemory)(int screen);
+ FILE *proc;
+ unsigned long mem;
+ unsigned start, stop;
+ char line[BUFSIZ];
+ Uint32 size;
+
+ mem = (unsigned long)SDL_NAME(XDGAGetMappedMemory)(DGA_Screen);
+ size = 0;
+ proc = fopen("/proc/self/maps", "r");
+ if ( proc ) {
+ while ( fgets(line, sizeof(line)-1, proc) ) {
+ SDL_sscanf(line, "%x-%x", &start, &stop);
+ if ( start == mem ) {
+ size = (Uint32)((stop-start)/1024);
+ break;
+ }
+ }
+ fclose(proc);
+ }
+ return(size);
+}
+
+#ifdef DGA_DEBUG
+static void PrintMode(SDL_NAME(XDGAMode) *mode)
+{
+ printf("Mode: %s (%dx%d) at %d bpp (%f refresh, %d pitch) num: %d\n",
+ mode->name,
+ mode->viewportWidth, mode->viewportHeight,
+ mode->depth == 24 ? mode->bitsPerPixel : mode->depth,
+ mode->verticalRefresh, mode->bytesPerScanline, mode->num);
+ printf("\tRGB: 0x%8.8x 0x%8.8x 0x%8.8x (%d - %s)\n",
+ mode->redMask, mode->greenMask, mode->blueMask,
+ mode->visualClass,
+ mode->visualClass == TrueColor ? "truecolor" :
+ mode->visualClass == DirectColor ? "directcolor" :
+ mode->visualClass == PseudoColor ? "pseudocolor" : "unknown");
+ printf("\tFlags: ");
+ if ( mode->flags & XDGAConcurrentAccess )
+ printf(" XDGAConcurrentAccess");
+ if ( mode->flags & XDGASolidFillRect )
+ printf(" XDGASolidFillRect");
+ if ( mode->flags & XDGABlitRect )
+ printf(" XDGABlitRect");
+ if ( mode->flags & XDGABlitTransRect )
+ printf(" XDGABlitTransRect");
+ if ( mode->flags & XDGAPixmap )
+ printf(" XDGAPixmap");
+ if ( mode->flags & XDGAInterlaced )
+ printf(" XDGAInterlaced");
+ if ( mode->flags & XDGADoublescan )
+ printf(" XDGADoublescan");
+ if ( mode->viewportFlags & XDGAFlipRetrace )
+ printf(" XDGAFlipRetrace");
+ if ( mode->viewportFlags & XDGAFlipImmediate )
+ printf(" XDGAFlipImmediate");
+ printf("\n");
+}
+#endif /* DGA_DEBUG */
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ const SDL_NAME(XDGAMode) *a = (const SDL_NAME(XDGAMode) *)va;
+ const SDL_NAME(XDGAMode) *b = (const SDL_NAME(XDGAMode) *)vb;
+
+ if ( (a->viewportWidth == b->viewportWidth) &&
+ (b->viewportHeight == a->viewportHeight) ) {
+ /* Prefer 32 bpp over 24 bpp, 16 bpp over 15 bpp */
+ int a_bpp = a->depth == 24 ? a->bitsPerPixel : a->depth;
+ int b_bpp = b->depth == 24 ? b->bitsPerPixel : b->depth;
+ if ( a_bpp != b_bpp ) {
+ return b_bpp - a_bpp;
+ }
+ /* Prefer DirectColor visuals, for gamma support */
+ if ( a->visualClass == DirectColor && b->visualClass != DirectColor )
+ return -1;
+ if ( b->visualClass == DirectColor && a->visualClass != DirectColor )
+ return 1;
+ /* Maintain server refresh rate sorting */
+ return a->num - b->num;
+ } else if ( a->viewportWidth == b->viewportWidth ) {
+ return b->viewportHeight - a->viewportHeight;
+ } else {
+ return b->viewportWidth - a->viewportWidth;
+ }
+}
+static void UpdateHWInfo(_THIS, SDL_NAME(XDGAMode) *mode)
+{
+ this->info.wm_available = 0;
+ this->info.hw_available = 1;
+ if ( mode->flags & XDGABlitRect ) {
+ this->info.blit_hw = 1;
+ } else {
+ this->info.blit_hw = 0;
+ }
+ if ( mode->flags & XDGABlitTransRect ) {
+ this->info.blit_hw_CC = 1;
+ } else {
+ this->info.blit_hw_CC = 0;
+ }
+ if ( mode->flags & XDGASolidFillRect ) {
+ this->info.blit_fill = 1;
+ } else {
+ this->info.blit_fill = 0;
+ }
+ this->info.video_mem = get_video_size(this);
+}
+
+static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ const char *env;
+ const char *display;
+ int event_base, error_base;
+ int major_version, minor_version;
+ Visual *visual;
+ SDL_NAME(XDGAMode) *modes;
+ int i, num_modes;
+
+ /* Open the X11 display */
+ display = NULL; /* Get it from DISPLAY environment variable */
+
+ DGA_Display = XOpenDisplay(display);
+ if ( DGA_Display == NULL ) {
+ SDL_SetError("Couldn't open X11 display");
+ return(-1);
+ }
+
+ /* Check for the DGA extension */
+ if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) ||
+ ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) {
+ SDL_SetError("DGA extension not available");
+ XCloseDisplay(DGA_Display);
+ return(-1);
+ }
+ if ( major_version < 2 ) {
+ SDL_SetError("DGA driver requires DGA 2.0 or newer");
+ XCloseDisplay(DGA_Display);
+ return(-1);
+ }
+ DGA_event_base = event_base;
+
+ /* Determine the current screen size */
+ this->info.current_w = DisplayWidth(DGA_Display, DGA_Screen);
+ this->info.current_h = DisplayHeight(DGA_Display, DGA_Screen);
+
+ /* Determine the current screen depth */
+ visual = DefaultVisual(DGA_Display, DGA_Screen);
+ {
+ XPixmapFormatValues *pix_format;
+ int i, num_formats;
+
+ vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen);
+ pix_format = XListPixmapFormats(DGA_Display, &num_formats);
+ if ( pix_format == NULL ) {
+ SDL_SetError("Couldn't determine screen formats");
+ XCloseDisplay(DGA_Display);
+ return(-1);
+ }
+ for ( i=0; i<num_formats; ++i ) {
+ if ( vformat->BitsPerPixel == pix_format[i].depth )
+ break;
+ }
+ if ( i != num_formats )
+ vformat->BitsPerPixel = pix_format[i].bits_per_pixel;
+ XFree((char *)pix_format);
+ }
+ if ( vformat->BitsPerPixel > 8 ) {
+ vformat->Rmask = visual->red_mask;
+ vformat->Gmask = visual->green_mask;
+ vformat->Bmask = visual->blue_mask;
+ }
+
+ /* Open access to the framebuffer */
+ if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) {
+ SDL_SetError("Unable to map the video memory");
+ XCloseDisplay(DGA_Display);
+ return(-1);
+ }
+
+ /* Allow environment override of screensaver disable. */
+ env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
+ if ( env ) {
+ allow_screensaver = SDL_atoi(env);
+ } else {
+#ifdef SDL_VIDEO_DISABLE_SCREENSAVER
+ allow_screensaver = 0;
+#else
+ allow_screensaver = 1;
+#endif
+ }
+
+ /* Query for the list of available video modes */
+ modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
+ SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
+ for ( i=0; i<num_modes; ++i ) {
+ if ( ((modes[i].visualClass == PseudoColor) ||
+ (modes[i].visualClass == DirectColor) ||
+ (modes[i].visualClass == TrueColor)) &&
+ !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
+#ifdef DGA_DEBUG
+ PrintMode(&modes[i]);
+#endif
+ DGA_AddMode(this, modes[i].bitsPerPixel,
+ modes[i].viewportWidth,
+ modes[i].viewportHeight);
+ }
+ }
+ UpdateHWInfo(this, modes);
+ XFree(modes);
+
+ /* Create the hardware surface lock mutex */
+ hw_lock = SDL_CreateMutex();
+ if ( hw_lock == NULL ) {
+ SDL_SetError("Unable to create lock mutex");
+ DGA_VideoQuit(this);
+ return(-1);
+ }
+
+#ifdef LOCK_DGA_DISPLAY
+ /* Create the event lock so we're thread-safe.. :-/ */
+ event_lock = SDL_CreateMutex();
+#endif /* LOCK_DGA_DISPLAY */
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+}
+
+/* Various screen update functions available */
+static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ SDL_NAME(XDGAMode) *modes;
+ int i, num_modes;
+ SDL_NAME(XDGADevice) *mode;
+ int screen_len;
+ Uint8 *surfaces_mem;
+ int surfaces_len;
+
+ /* Free any previous colormap */
+ if ( DGA_colormap ) {
+ XFreeColormap(DGA_Display, DGA_colormap);
+ DGA_colormap = 0;
+ }
+
+ /* Search for a matching video mode */
+ modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
+ SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
+ for ( i=0; i<num_modes; ++i ) {
+ int depth;
+
+ depth = modes[i].depth;
+ if ( depth == 24 ) { /* Distinguish between 24 and 32 bpp */
+ depth = modes[i].bitsPerPixel;
+ }
+ if ( (depth == bpp) &&
+ (modes[i].viewportWidth == width) &&
+ (modes[i].viewportHeight == height) &&
+ ((modes[i].visualClass == PseudoColor) ||
+ (modes[i].visualClass == DirectColor) ||
+ (modes[i].visualClass == TrueColor)) &&
+ !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
+ break;
+ }
+ }
+ if ( i == num_modes ) {
+ SDL_SetError("No matching video mode found");
+ return(NULL);
+ }
+#ifdef DGA_DEBUG
+ PrintMode(&modes[i]);
+#endif
+
+ /* Set the video mode */
+ mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num);
+ XFree(modes);
+ if ( mode == NULL ) {
+ SDL_SetError("Unable to switch to requested mode");
+ return(NULL);
+ }
+ DGA_visualClass = mode->mode.visualClass;
+ memory_base = (Uint8 *)mode->data;
+ memory_pitch = mode->mode.bytesPerScanline;
+
+ /* Set up the new mode framebuffer */
+ current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
+ current->w = mode->mode.viewportWidth;
+ current->h = mode->mode.viewportHeight;
+ current->pitch = memory_pitch;
+ current->pixels = memory_base;
+ if ( ! SDL_ReallocFormat(current, mode->mode.bitsPerPixel,
+ mode->mode.redMask,
+ mode->mode.greenMask,
+ mode->mode.blueMask, 0) ) {
+ return(NULL);
+ }
+ screen_len = current->h*current->pitch;
+
+ /* Create a colormap if necessary */
+ if ( (DGA_visualClass == PseudoColor) ||
+ (DGA_visualClass == DirectColor) ) {
+ DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,
+ mode, AllocAll);
+ if ( DGA_visualClass == PseudoColor ) {
+ current->flags |= SDL_HWPALETTE;
+ } else {
+ /* Initialize the colormap to the identity mapping */
+ SDL_GetGammaRamp(0, 0, 0);
+ this->screen = current;
+ DGA_SetGammaRamp(this, this->gamma);
+ this->screen = NULL;
+ }
+ } else {
+ DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen,
+ mode, AllocNone);
+ }
+ SDL_NAME(XDGAInstallColormap)(DGA_Display, DGA_Screen, DGA_colormap);
+
+ /* Update the hardware capabilities */
+ UpdateHWInfo(this, &mode->mode);
+
+ /* Set up the information for hardware surfaces */
+ surfaces_mem = (Uint8 *)current->pixels + screen_len;
+ surfaces_len = (mode->mode.imageHeight*current->pitch - screen_len);
+
+ /* Update for double-buffering, if we can */
+ SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, 0, 0, XDGAFlipRetrace);
+ if ( flags & SDL_DOUBLEBUF ) {
+ if ( mode->mode.imageHeight >= (current->h*2) ) {
+ current->flags |= SDL_DOUBLEBUF;
+ flip_page = 0;
+ flip_yoffset[0] = 0;
+ flip_yoffset[1] = current->h;
+ flip_address[0] = memory_base;
+ flip_address[1] = memory_base+screen_len;
+ surfaces_mem += screen_len;
+ surfaces_len -= screen_len;
+ }
+ }
+
+ /* Allocate memory tracking for hardware surfaces */
+ DGA_FreeHWSurfaces(this);
+ if ( surfaces_len < 0 ) {
+ surfaces_len = 0;
+ }
+ DGA_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
+
+ /* Expose the back buffer as surface memory */
+ if ( current->flags & SDL_DOUBLEBUF ) {
+ this->screen = current;
+ DGA_FlipHWSurface(this, current);
+ this->screen = NULL;
+ }
+
+ /* Set the update rectangle function */
+ this->UpdateRects = DGA_DirectUpdate;
+
+ /* Enable mouse and keyboard support */
+ { long input_mask;
+ input_mask = (KeyPressMask | KeyReleaseMask);
+ input_mask |= (ButtonPressMask | ButtonReleaseMask);
+ input_mask |= PointerMotionMask;
+ SDL_NAME(XDGASelectInput)(DGA_Display, DGA_Screen, input_mask);
+ }
+
+ /* We're done */
+ return(current);
+}
+
+#ifdef DGA_DEBUG
+static void DGA_DumpHWSurfaces(_THIS)
+{
+ vidmem_bucket *bucket;
+
+ printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal);
+ printf("\n");
+ printf(" Base Size\n");
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free");
+ if ( bucket->prev ) {
+ if ( bucket->base != bucket->prev->base+bucket->prev->size ) {
+ printf("Warning, corrupt bucket list! (prev)\n");
+ }
+ } else {
+ if ( bucket != &surfaces ) {
+ printf("Warning, corrupt bucket list! (!prev)\n");
+ }
+ }
+ if ( bucket->next ) {
+ if ( bucket->next->base != bucket->base+bucket->size ) {
+ printf("Warning, corrupt bucket list! (next)\n");
+ }
+ }
+ }
+ printf("\n");
+}
+#endif
+
+static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size)
+{
+ vidmem_bucket *bucket;
+
+ surfaces_memtotal = size;
+ surfaces_memleft = size;
+
+ if ( surfaces_memleft > 0 ) {
+ bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket));
+ if ( bucket == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ bucket->prev = &surfaces;
+ bucket->used = 0;
+ bucket->dirty = 0;
+ bucket->base = base;
+ bucket->size = size;
+ bucket->next = NULL;
+ } else {
+ bucket = NULL;
+ }
+
+ surfaces.prev = NULL;
+ surfaces.used = 1;
+ surfaces.dirty = 0;
+ surfaces.base = screen->pixels;
+ surfaces.size = (unsigned int)((long)base - (long)surfaces.base);
+ surfaces.next = bucket;
+ screen->hwdata = (struct private_hwdata *)((char*)&surfaces);
+ return(0);
+}
+static void DGA_FreeHWSurfaces(_THIS)
+{
+ vidmem_bucket *bucket, *freeable;
+
+ bucket = surfaces.next;
+ while ( bucket ) {
+ freeable = bucket;
+ bucket = bucket->next;
+ SDL_free(freeable);
+ }
+ surfaces.next = NULL;
+}
+
+static __inline__ void DGA_AddBusySurface(SDL_Surface *surface)
+{
+ ((vidmem_bucket *)surface->hwdata)->dirty = 1;
+}
+
+static __inline__ int DGA_IsSurfaceBusy(SDL_Surface *surface)
+{
+ return ((vidmem_bucket *)surface->hwdata)->dirty;
+}
+
+static __inline__ void DGA_WaitBusySurfaces(_THIS)
+{
+ vidmem_bucket *bucket;
+
+ /* Wait for graphic operations to complete */
+ SDL_NAME(XDGASync)(DGA_Display, DGA_Screen);
+
+ /* Clear all surface dirty bits */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ bucket->dirty = 0;
+ }
+}
+
+static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ vidmem_bucket *bucket;
+ int size;
+ int extra;
+ int retval = 0;
+
+/* Temporarily, we only allow surfaces the same width as display.
+ Some blitters require the pitch between two hardware surfaces
+ to be the same. Others have interesting alignment restrictions.
+*/
+if ( surface->pitch > SDL_VideoSurface->pitch ) {
+ SDL_SetError("Surface requested wider than screen");
+ return(-1);
+}
+surface->pitch = SDL_VideoSurface->pitch;
+ size = surface->h * surface->pitch;
+#ifdef DGA_DEBUG
+ fprintf(stderr, "Allocating bucket of %d bytes\n", size);
+#endif
+ LOCK_DISPLAY();
+
+ /* Quick check for available mem */
+ if ( size > surfaces_memleft ) {
+ SDL_SetError("Not enough video memory");
+ retval = -1;
+ goto done;
+ }
+
+ /* Search for an empty bucket big enough */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ if ( ! bucket->used && (size <= bucket->size) ) {
+ break;
+ }
+ }
+ if ( bucket == NULL ) {
+ SDL_SetError("Video memory too fragmented");
+ retval = -1;
+ goto done;
+ }
+
+ /* Create a new bucket for left-over memory */
+ extra = (bucket->size - size);
+ if ( extra ) {
+ vidmem_bucket *newbucket;
+
+#ifdef DGA_DEBUG
+ fprintf(stderr, "Adding new free bucket of %d bytes\n", extra);
+#endif
+ newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket));
+ if ( newbucket == NULL ) {
+ SDL_OutOfMemory();
+ retval = -1;
+ goto done;
+ }
+ newbucket->prev = bucket;
+ newbucket->used = 0;
+ newbucket->base = bucket->base+size;
+ newbucket->size = extra;
+ newbucket->next = bucket->next;
+ if ( bucket->next ) {
+ bucket->next->prev = newbucket;
+ }
+ bucket->next = newbucket;
+ }
+
+ /* Set the current bucket values and return it! */
+ bucket->used = 1;
+ bucket->size = size;
+ bucket->dirty = 0;
+#ifdef DGA_DEBUG
+ fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
+#endif
+ surfaces_memleft -= size;
+ surface->flags |= SDL_HWSURFACE;
+ surface->pixels = bucket->base;
+ surface->hwdata = (struct private_hwdata *)bucket;
+done:
+ UNLOCK_DISPLAY();
+ return(retval);
+}
+static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ vidmem_bucket *bucket, *freeable;
+
+ /* Wait for any pending operations involving this surface */
+ if ( DGA_IsSurfaceBusy(surface) ) {
+ LOCK_DISPLAY();
+ DGA_WaitBusySurfaces(this);
+ UNLOCK_DISPLAY();
+ }
+
+ /* Look for the bucket in the current list */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ if ( bucket == (vidmem_bucket *)surface->hwdata ) {
+ break;
+ }
+ }
+ if ( bucket && bucket->used ) {
+ /* Add the memory back to the total */
+#ifdef DGA_DEBUG
+ printf("Freeing bucket of %d bytes\n", bucket->size);
+#endif
+ surfaces_memleft += bucket->size;
+
+ /* Can we merge the space with surrounding buckets? */
+ bucket->used = 0;
+ if ( bucket->next && ! bucket->next->used ) {
+#ifdef DGA_DEBUG
+ printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
+#endif
+ freeable = bucket->next;
+ bucket->size += bucket->next->size;
+ bucket->next = bucket->next->next;
+ if ( bucket->next ) {
+ bucket->next->prev = bucket;
+ }
+ SDL_free(freeable);
+ }
+ if ( bucket->prev && ! bucket->prev->used ) {
+#ifdef DGA_DEBUG
+ printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
+#endif
+ freeable = bucket;
+ bucket->prev->size += bucket->size;
+ bucket->prev->next = bucket->next;
+ if ( bucket->next ) {
+ bucket->next->prev = bucket->prev;
+ }
+ SDL_free(freeable);
+ }
+ }
+ surface->pixels = NULL;
+ surface->hwdata = NULL;
+}
+
+static __inline__ void DGA_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y)
+{
+ *x = (long)((Uint8 *)dst->pixels - memory_base)%memory_pitch;
+ *y = (long)((Uint8 *)dst->pixels - memory_base)/memory_pitch;
+}
+
+static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
+{
+ int x, y;
+ unsigned int w, h;
+
+ /* Don't fill the visible part of the screen, wait until flipped */
+ LOCK_DISPLAY();
+ if ( was_flipped && (dst == this->screen) ) {
+ while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
+ /* Keep waiting for the hardware ... */ ;
+ was_flipped = 0;
+ }
+ DGA_dst_to_xy(this, dst, &x, &y);
+ x += rect->x;
+ y += rect->y;
+ w = rect->w;
+ h = rect->h;
+#if 0
+ printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x, y);
+#endif
+ SDL_NAME(XDGAFillRectangle)(DGA_Display, DGA_Screen, x, y, w, h, color);
+ if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
+ XFlush(DGA_Display);
+ }
+ DGA_AddBusySurface(dst);
+ UNLOCK_DISPLAY();
+ return(0);
+}
+
+static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_VideoDevice *this;
+ int srcx, srcy;
+ int dstx, dsty;
+ unsigned int w, h;
+
+ this = current_video;
+ /* Don't blit to the visible part of the screen, wait until flipped */
+ LOCK_DISPLAY();
+ if ( was_flipped && (dst == this->screen) ) {
+ while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
+ /* Keep waiting for the hardware ... */ ;
+ was_flipped = 0;
+ }
+ DGA_dst_to_xy(this, src, &srcx, &srcy);
+ srcx += srcrect->x;
+ srcy += srcrect->y;
+ DGA_dst_to_xy(this, dst, &dstx, &dsty);
+ dstx += dstrect->x;
+ dsty += dstrect->y;
+ w = srcrect->w;
+ h = srcrect->h;
+#if 0
+ printf("Blitting %dx%d from %d,%d to %d,%d\n", w, h, srcx, srcy, dstx, dsty);
+#endif
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ SDL_NAME(XDGACopyTransparentArea)(DGA_Display, DGA_Screen,
+ srcx, srcy, w, h, dstx, dsty, src->format->colorkey);
+ } else {
+ SDL_NAME(XDGACopyArea)(DGA_Display, DGA_Screen,
+ srcx, srcy, w, h, dstx, dsty);
+ }
+ if ( !(this->screen->flags & SDL_DOUBLEBUF) ) {
+ XFlush(DGA_Display);
+ }
+ DGA_AddBusySurface(src);
+ DGA_AddBusySurface(dst);
+ UNLOCK_DISPLAY();
+ return(0);
+}
+
+static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ int accelerated;
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! this->info.blit_hw_A ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! this->info.blit_hw_CC ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+ src->map->hw_blit = HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+static __inline__ void DGA_WaitFlip(_THIS)
+{
+ if ( was_flipped ) {
+ while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) )
+ /* Keep waiting for the hardware ... */ ;
+ was_flipped = 0;
+ }
+}
+
+static int DGA_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface == this->screen ) {
+ SDL_mutexP(hw_lock);
+ LOCK_DISPLAY();
+ if ( DGA_IsSurfaceBusy(surface) ) {
+ DGA_WaitBusySurfaces(this);
+ }
+ DGA_WaitFlip(this);
+ UNLOCK_DISPLAY();
+ } else {
+ if ( DGA_IsSurfaceBusy(surface) ) {
+ LOCK_DISPLAY();
+ DGA_WaitBusySurfaces(this);
+ UNLOCK_DISPLAY();
+ }
+ }
+ return(0);
+}
+static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+}
+
+static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ /* Wait for vertical retrace and then flip display */
+ LOCK_DISPLAY();
+ if ( DGA_IsSurfaceBusy(this->screen) ) {
+ DGA_WaitBusySurfaces(this);
+ }
+ DGA_WaitFlip(this);
+ SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen,
+ 0, flip_yoffset[flip_page], XDGAFlipRetrace);
+ XFlush(DGA_Display);
+ UNLOCK_DISPLAY();
+ was_flipped = 1;
+ flip_page = !flip_page;
+
+ surface->pixels = flip_address[flip_page];
+ return(0);
+}
+
+static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ /* The application is already updating the visible video memory */
+ return;
+}
+
+static int DGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ XColor *xcmap;
+
+ /* This happens on initialization */
+ if ( ! DGA_colormap ) {
+ return(0);
+ }
+ xcmap = SDL_stack_alloc(XColor, ncolors);
+ for ( i=0; i<ncolors; ++i ) {
+ xcmap[i].pixel = firstcolor + i;
+ xcmap[i].red = (colors[i].r<<8)|colors[i].r;
+ xcmap[i].green = (colors[i].g<<8)|colors[i].g;
+ xcmap[i].blue = (colors[i].b<<8)|colors[i].b;
+ xcmap[i].flags = (DoRed|DoGreen|DoBlue);
+ }
+ LOCK_DISPLAY();
+ XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
+ XSync(DGA_Display, False);
+ UNLOCK_DISPLAY();
+ SDL_stack_free(xcmap);
+
+ /* That was easy. :) */
+ return(1);
+}
+
+int DGA_SetGammaRamp(_THIS, Uint16 *ramp)
+{
+ int i, ncolors;
+ XColor xcmap[256];
+
+ /* See if actually setting the gamma is supported */
+ if ( DGA_visualClass != DirectColor ) {
+ SDL_SetError("Gamma correction not supported on this visual");
+ return(-1);
+ }
+
+ /* Calculate the appropriate palette for the given gamma ramp */
+ if ( this->screen->format->BitsPerPixel <= 16 ) {
+ ncolors = 64; /* Is this right? */
+ } else {
+ ncolors = 256;
+ }
+ for ( i=0; i<ncolors; ++i ) {
+ Uint8 c = (256 * i / ncolors);
+ xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c);
+ xcmap[i].red = ramp[0*256+c];
+ xcmap[i].green = ramp[1*256+c];
+ xcmap[i].blue = ramp[2*256+c];
+ xcmap[i].flags = (DoRed|DoGreen|DoBlue);
+ }
+ LOCK_DISPLAY();
+ XStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors);
+ XSync(DGA_Display, False);
+ UNLOCK_DISPLAY();
+ return(0);
+}
+
+void DGA_VideoQuit(_THIS)
+{
+ int i, j;
+
+ if ( DGA_Display ) {
+ /* Free colormap, if necessary */
+ if ( DGA_colormap ) {
+ XFreeColormap(DGA_Display, DGA_colormap);
+ DGA_colormap = 0;
+ }
+
+ /* Unmap memory and reset video mode */
+ SDL_NAME(XDGACloseFramebuffer)(DGA_Display, DGA_Screen);
+ if ( this->screen ) {
+ /* Tell SDL not to free the pixels */
+ DGA_FreeHWSurface(this, this->screen);
+ }
+ SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, 0);
+
+ /* Clear the lock mutex */
+ if ( hw_lock != NULL ) {
+ SDL_DestroyMutex(hw_lock);
+ hw_lock = NULL;
+ }
+#ifdef LOCK_DGA_DISPLAY
+ if ( event_lock != NULL ) {
+ SDL_DestroyMutex(event_lock);
+ event_lock = NULL;
+ }
+#endif /* LOCK_DGA_DISPLAY */
+
+ /* Clean up defined video modes */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ for ( j=0; SDL_modelist[i][j]; ++j ) {
+ SDL_free(SDL_modelist[i][j]);
+ }
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ /* Clean up the memory bucket list */
+ DGA_FreeHWSurfaces(this);
+
+ /* Close up the display */
+ XCloseDisplay(DGA_Display);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.h b/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.h
new file mode 100644
index 0000000..bd2ecb8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dga/SDL_dgavideo.h
@@ -0,0 +1,124 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_dgavideo_h
+#define _SDL_dgavideo_h
+
+#include <X11/Xlib.h>
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include <X11/Xproto.h>
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+/* Define this if you need the DGA driver to be thread-safe */
+#define LOCK_DGA_DISPLAY
+#ifdef LOCK_DGA_DISPLAY
+#define LOCK_DISPLAY() SDL_mutexP(event_lock)
+#define UNLOCK_DISPLAY() SDL_mutexV(event_lock)
+#else
+#define LOCK_DISPLAY()
+#define UNLOCK_DISPLAY()
+#endif
+
+
+/* This is the structure we use to keep track of video memory */
+typedef struct vidmem_bucket {
+ struct vidmem_bucket *prev;
+ int used;
+ int dirty;
+ Uint8 *base;
+ unsigned int size;
+ struct vidmem_bucket *next;
+} vidmem_bucket;
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ Display *DGA_Display;
+ Colormap DGA_colormap;
+ int visualClass;
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+ /* Information for the video surface */
+ Uint8 *memory_base;
+ int memory_pitch;
+ SDL_mutex *hw_lock;
+ int sync_needed;
+ int was_flipped;
+
+ /* Information for hardware surfaces */
+ vidmem_bucket surfaces;
+ int surfaces_memtotal;
+ int surfaces_memleft;
+
+ /* Information for double-buffering */
+ int flip_page;
+ int flip_yoffset[2];
+ Uint8 *flip_address[2];
+
+ /* Used to handle DGA events */
+ int event_base;
+#ifdef LOCK_DGA_DISPLAY
+ SDL_mutex *event_lock;
+#endif
+
+ /* Screensaver settings */
+ int allow_screensaver;
+};
+
+/* Old variable names */
+#define DGA_Display (this->hidden->DGA_Display)
+#define DGA_Screen DefaultScreen(DGA_Display)
+#define DGA_colormap (this->hidden->DGA_colormap)
+#define DGA_visualClass (this->hidden->visualClass)
+#define memory_base (this->hidden->memory_base)
+#define memory_pitch (this->hidden->memory_pitch)
+#define flip_page (this->hidden->flip_page)
+#define flip_yoffset (this->hidden->flip_yoffset)
+#define flip_address (this->hidden->flip_address)
+#define sync_needed (this->hidden->sync_needed)
+#define was_flipped (this->hidden->was_flipped)
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define surfaces (this->hidden->surfaces)
+#define surfaces_memtotal (this->hidden->surfaces_memtotal)
+#define surfaces_memleft (this->hidden->surfaces_memleft)
+#define hw_lock (this->hidden->hw_lock)
+#define DGA_event_base (this->hidden->event_base)
+#define event_lock (this->hidden->event_lock)
+#define allow_screensaver (this->hidden->allow_screensaver)
+
+#endif /* _SDL_dgavideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.c b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.c
new file mode 100644
index 0000000..246b75b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.c
@@ -0,0 +1,219 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting DirectFB input events into SDL events */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <directfb.h>
+
+#include "SDL.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_DirectFB_video.h"
+#include "SDL_DirectFB_events.h"
+
+/* The translation tables from a DirectFB keycode to a SDL keysym */
+static SDLKey keymap[256];
+static SDL_keysym *DirectFB_TranslateKey (DFBInputEvent *ev, SDL_keysym *keysym);
+static int DirectFB_TranslateButton (DFBInputEvent *ev);
+
+static int posted = 0;
+
+
+void DirectFB_PumpEvents (_THIS)
+{
+ DFBInputEvent evt;
+
+ while (HIDDEN->eventbuffer->GetEvent (HIDDEN->eventbuffer,
+ DFB_EVENT (&evt)) == DFB_OK)
+ {
+ SDL_keysym keysym;
+
+ switch (evt.type)
+ {
+ case DIET_BUTTONPRESS:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED,
+ DirectFB_TranslateButton (&evt), 0, 0);
+ break;
+ case DIET_BUTTONRELEASE:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED,
+ DirectFB_TranslateButton (&evt), 0, 0);
+ break;
+ case DIET_KEYPRESS:
+ posted += SDL_PrivateKeyboard(SDL_PRESSED, DirectFB_TranslateKey(&evt, &keysym));
+ break;
+ case DIET_KEYRELEASE:
+ posted += SDL_PrivateKeyboard(SDL_RELEASED, DirectFB_TranslateKey(&evt, &keysym));
+ break;
+ case DIET_AXISMOTION:
+ if (evt.flags & DIEF_AXISREL)
+ {
+ if (evt.axis == DIAI_X)
+ posted += SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0);
+ else if (evt.axis == DIAI_Y)
+ posted += SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel);
+ }
+ else if (evt.flags & DIEF_AXISABS)
+ {
+ static int last_x, last_y;
+ if (evt.axis == DIAI_X)
+ last_x = evt.axisabs;
+ else if (evt.axis == DIAI_Y)
+ last_y = evt.axisabs;
+ posted += SDL_PrivateMouseMotion(0, 0, last_x, last_y);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+void DirectFB_InitOSKeymap (_THIS)
+{
+ int i;
+
+ /* Initialize the DirectFB key translation table */
+ for (i=0; i<SDL_arraysize(keymap); ++i)
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[DIKI_A - DIKI_UNKNOWN] = SDLK_a;
+ keymap[DIKI_B - DIKI_UNKNOWN] = SDLK_b;
+ keymap[DIKI_C - DIKI_UNKNOWN] = SDLK_c;
+ keymap[DIKI_D - DIKI_UNKNOWN] = SDLK_d;
+ keymap[DIKI_E - DIKI_UNKNOWN] = SDLK_e;
+ keymap[DIKI_F - DIKI_UNKNOWN] = SDLK_f;
+ keymap[DIKI_G - DIKI_UNKNOWN] = SDLK_g;
+ keymap[DIKI_H - DIKI_UNKNOWN] = SDLK_h;
+ keymap[DIKI_I - DIKI_UNKNOWN] = SDLK_i;
+ keymap[DIKI_J - DIKI_UNKNOWN] = SDLK_j;
+ keymap[DIKI_K - DIKI_UNKNOWN] = SDLK_k;
+ keymap[DIKI_L - DIKI_UNKNOWN] = SDLK_l;
+ keymap[DIKI_M - DIKI_UNKNOWN] = SDLK_m;
+ keymap[DIKI_N - DIKI_UNKNOWN] = SDLK_n;
+ keymap[DIKI_O - DIKI_UNKNOWN] = SDLK_o;
+ keymap[DIKI_P - DIKI_UNKNOWN] = SDLK_p;
+ keymap[DIKI_Q - DIKI_UNKNOWN] = SDLK_q;
+ keymap[DIKI_R - DIKI_UNKNOWN] = SDLK_r;
+ keymap[DIKI_S - DIKI_UNKNOWN] = SDLK_s;
+ keymap[DIKI_T - DIKI_UNKNOWN] = SDLK_t;
+ keymap[DIKI_U - DIKI_UNKNOWN] = SDLK_u;
+ keymap[DIKI_V - DIKI_UNKNOWN] = SDLK_v;
+ keymap[DIKI_W - DIKI_UNKNOWN] = SDLK_w;
+ keymap[DIKI_X - DIKI_UNKNOWN] = SDLK_x;
+ keymap[DIKI_Y - DIKI_UNKNOWN] = SDLK_y;
+ keymap[DIKI_Z - DIKI_UNKNOWN] = SDLK_z;
+
+ keymap[DIKI_0 - DIKI_UNKNOWN] = SDLK_0;
+ keymap[DIKI_1 - DIKI_UNKNOWN] = SDLK_1;
+ keymap[DIKI_2 - DIKI_UNKNOWN] = SDLK_2;
+ keymap[DIKI_3 - DIKI_UNKNOWN] = SDLK_3;
+ keymap[DIKI_4 - DIKI_UNKNOWN] = SDLK_4;
+ keymap[DIKI_5 - DIKI_UNKNOWN] = SDLK_5;
+ keymap[DIKI_6 - DIKI_UNKNOWN] = SDLK_6;
+ keymap[DIKI_7 - DIKI_UNKNOWN] = SDLK_7;
+ keymap[DIKI_8 - DIKI_UNKNOWN] = SDLK_8;
+ keymap[DIKI_9 - DIKI_UNKNOWN] = SDLK_9;
+
+ keymap[DIKI_F1 - DIKI_UNKNOWN] = SDLK_F1;
+ keymap[DIKI_F2 - DIKI_UNKNOWN] = SDLK_F2;
+ keymap[DIKI_F3 - DIKI_UNKNOWN] = SDLK_F3;
+ keymap[DIKI_F4 - DIKI_UNKNOWN] = SDLK_F4;
+ keymap[DIKI_F5 - DIKI_UNKNOWN] = SDLK_F5;
+ keymap[DIKI_F6 - DIKI_UNKNOWN] = SDLK_F6;
+ keymap[DIKI_F7 - DIKI_UNKNOWN] = SDLK_F7;
+ keymap[DIKI_F8 - DIKI_UNKNOWN] = SDLK_F8;
+ keymap[DIKI_F9 - DIKI_UNKNOWN] = SDLK_F9;
+ keymap[DIKI_F10 - DIKI_UNKNOWN] = SDLK_F10;
+ keymap[DIKI_F11 - DIKI_UNKNOWN] = SDLK_F11;
+ keymap[DIKI_F12 - DIKI_UNKNOWN] = SDLK_F12;
+
+ keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDLK_ESCAPE;
+ keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDLK_LEFT;
+ keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDLK_RIGHT;
+ keymap[DIKI_UP - DIKI_UNKNOWN] = SDLK_UP;
+ keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDLK_DOWN;
+ keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDLK_LCTRL;
+ keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDLK_RCTRL;
+ keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDLK_LSHIFT;
+ keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDLK_RSHIFT;
+ keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDLK_LALT;
+ keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDLK_RALT;
+ keymap[DIKI_TAB - DIKI_UNKNOWN] = SDLK_TAB;
+ keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDLK_RETURN;
+ keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDLK_SPACE;
+ keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDLK_BACKSPACE;
+ keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDLK_INSERT;
+ keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDLK_DELETE;
+ keymap[DIKI_HOME - DIKI_UNKNOWN] = SDLK_HOME;
+ keymap[DIKI_END - DIKI_UNKNOWN] = SDLK_END;
+ keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDLK_PAGEUP;
+ keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDLK_PAGEDOWN;
+ keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDLK_CAPSLOCK;
+ keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDLK_NUMLOCK;
+ keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDLK_SCROLLOCK;
+ keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDLK_PRINT;
+ keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDLK_PAUSE;
+ keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDLK_KP_DIVIDE;
+ keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDLK_KP_MULTIPLY;
+ keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDLK_KP_MINUS;
+ keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDLK_KP_PLUS;
+ keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDLK_KP_ENTER;
+}
+
+
+static SDL_keysym *DirectFB_TranslateKey (DFBInputEvent *ev, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = ev->key_id;
+ keysym->mod = KMOD_NONE; /* FIXME */
+ keysym->unicode = (DFB_KEY_TYPE (ev->key_symbol) == DIKT_UNICODE) ? ev->key_symbol : 0;
+
+ if (ev->key_symbol > 0 && ev->key_symbol < 128)
+ keysym->sym = ev->key_symbol;
+ else
+ keysym->sym = keymap[ev->key_id - DIKI_UNKNOWN];
+
+ return keysym;
+}
+
+static int DirectFB_TranslateButton (DFBInputEvent *ev)
+{
+ switch (ev->button)
+ {
+ case DIBI_LEFT:
+ return 1;
+ case DIBI_MIDDLE:
+ return 2;
+ case DIBI_RIGHT:
+ return 3;
+ default:
+ return 0;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.h b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.h
new file mode 100644
index 0000000..20f3967
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_events.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_DirectFB_video.h"
+
+/* Functions to be exported */
+extern void DirectFB_InitOSKeymap(_THIS);
+extern void DirectFB_PumpEvents(_THIS);
+
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_keys.h b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_keys.h
new file mode 100644
index 0000000..2868ee6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_keys.h
@@ -0,0 +1,135 @@
+
+#define SCANCODE_ESCAPE 1
+
+#define SCANCODE_1 2
+#define SCANCODE_2 3
+#define SCANCODE_3 4
+#define SCANCODE_4 5
+#define SCANCODE_5 6
+#define SCANCODE_6 7
+#define SCANCODE_7 8
+#define SCANCODE_8 9
+#define SCANCODE_9 10
+#define SCANCODE_0 11
+
+#define SCANCODE_MINUS 12
+#define SCANCODE_EQUAL 13
+
+#define SCANCODE_BACKSPACE 14
+#define SCANCODE_TAB 15
+
+#define SCANCODE_Q 16
+#define SCANCODE_W 17
+#define SCANCODE_E 18
+#define SCANCODE_R 19
+#define SCANCODE_T 20
+#define SCANCODE_Y 21
+#define SCANCODE_U 22
+#define SCANCODE_I 23
+#define SCANCODE_O 24
+#define SCANCODE_P 25
+#define SCANCODE_BRACKET_LEFT 26
+#define SCANCODE_BRACKET_RIGHT 27
+
+#define SCANCODE_ENTER 28
+
+#define SCANCODE_LEFTCONTROL 29
+
+#define SCANCODE_A 30
+#define SCANCODE_S 31
+#define SCANCODE_D 32
+#define SCANCODE_F 33
+#define SCANCODE_G 34
+#define SCANCODE_H 35
+#define SCANCODE_J 36
+#define SCANCODE_K 37
+#define SCANCODE_L 38
+#define SCANCODE_SEMICOLON 39
+#define SCANCODE_APOSTROPHE 40
+#define SCANCODE_GRAVE 41
+
+#define SCANCODE_LEFTSHIFT 42
+#define SCANCODE_BACKSLASH 43
+
+#define SCANCODE_Z 44
+#define SCANCODE_X 45
+#define SCANCODE_C 46
+#define SCANCODE_V 47
+#define SCANCODE_B 48
+#define SCANCODE_N 49
+#define SCANCODE_M 50
+#define SCANCODE_COMMA 51
+#define SCANCODE_PERIOD 52
+#define SCANCODE_SLASH 53
+
+#define SCANCODE_RIGHTSHIFT 54
+#define SCANCODE_KEYPADMULTIPLY 55
+
+#define SCANCODE_LEFTALT 56
+#define SCANCODE_SPACE 57
+#define SCANCODE_CAPSLOCK 58
+
+#define SCANCODE_F1 59
+#define SCANCODE_F2 60
+#define SCANCODE_F3 61
+#define SCANCODE_F4 62
+#define SCANCODE_F5 63
+#define SCANCODE_F6 64
+#define SCANCODE_F7 65
+#define SCANCODE_F8 66
+#define SCANCODE_F9 67
+#define SCANCODE_F10 68
+
+#define SCANCODE_NUMLOCK 69
+#define SCANCODE_SCROLLLOCK 70
+
+#define SCANCODE_KEYPAD7 71
+#define SCANCODE_CURSORUPLEFT 71
+#define SCANCODE_KEYPAD8 72
+#define SCANCODE_CURSORUP 72
+#define SCANCODE_KEYPAD9 73
+#define SCANCODE_CURSORUPRIGHT 73
+#define SCANCODE_KEYPADMINUS 74
+#define SCANCODE_KEYPAD4 75
+#define SCANCODE_CURSORLEFT 75
+#define SCANCODE_KEYPAD5 76
+#define SCANCODE_KEYPAD6 77
+#define SCANCODE_CURSORRIGHT 77
+#define SCANCODE_KEYPADPLUS 78
+#define SCANCODE_KEYPAD1 79
+#define SCANCODE_CURSORDOWNLEFT 79
+#define SCANCODE_KEYPAD2 80
+#define SCANCODE_CURSORDOWN 80
+#define SCANCODE_KEYPAD3 81
+#define SCANCODE_CURSORDOWNRIGHT 81
+#define SCANCODE_KEYPAD0 82
+#define SCANCODE_KEYPADPERIOD 83
+
+#define SCANCODE_LESS 86
+
+#define SCANCODE_F11 87
+#define SCANCODE_F12 88
+
+#define SCANCODE_KEYPADENTER 96
+#define SCANCODE_RIGHTCONTROL 97
+#define SCANCODE_CONTROL 97
+#define SCANCODE_KEYPADDIVIDE 98
+#define SCANCODE_PRINTSCREEN 99
+#define SCANCODE_RIGHTALT 100
+#define SCANCODE_BREAK 101 /* Beware: is 119 */
+#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
+
+#define SCANCODE_HOME 102
+#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */
+#define SCANCODE_PAGEUP 104
+#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */
+#define SCANCODE_END 107
+#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
+#define SCANCODE_PAGEDOWN 109
+#define SCANCODE_INSERT 110
+#define SCANCODE_REMOVE 111
+
+#define SCANCODE_RIGHTWIN 126
+#define SCANCODE_LEFTWIN 125
+
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.c b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.c
new file mode 100644
index 0000000..f665ec6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.c
@@ -0,0 +1,1171 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+
+ MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
+ CRTC2 support is inspired by mplayer's dfbmga driver
+ written by Ville Syrj��<syrjala@sci.fi>
+*/
+#include "SDL_config.h"
+
+/* DirectFB video driver implementation.
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <directfb.h>
+#include <directfb_version.h>
+
+#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_DirectFB_video.h"
+#include "SDL_DirectFB_events.h"
+#include "SDL_DirectFB_yuv.h"
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
+
+
+/* Initialization/Query functions */
+static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void DirectFB_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
+static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface);
+static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
+static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
+static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
+static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface);
+static int DirectFB_ShowWMCursor(_THIS, WMcursor *cursor);
+
+/* Various screen update functions available */
+static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+/* This is the rect EnumModes2 uses */
+struct DirectFBEnumRect {
+ SDL_Rect r;
+ struct DirectFBEnumRect* next;
+};
+
+static struct DirectFBEnumRect *enumlist = NULL;
+
+
+/* DirectFB driver bootstrap functions */
+
+static int DirectFB_Available(void)
+{
+ return 1;
+}
+
+static void DirectFB_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *DirectFB_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if (device)
+ {
+ SDL_memset (device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden));
+ }
+ if (device == NULL || device->hidden == NULL)
+ {
+ SDL_OutOfMemory();
+ if (device)
+ {
+ free (device);
+ }
+ return(0);
+ }
+ SDL_memset (device->hidden, 0, sizeof (*device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = DirectFB_VideoInit;
+ device->ListModes = DirectFB_ListModes;
+ device->SetVideoMode = DirectFB_SetVideoMode;
+ device->SetColors = DirectFB_SetColors;
+ device->UpdateRects = NULL;
+ device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
+ device->VideoQuit = DirectFB_VideoQuit;
+ device->AllocHWSurface = DirectFB_AllocHWSurface;
+ device->CheckHWBlit = DirectFB_CheckHWBlit;
+ device->FillHWRect = DirectFB_FillHWRect;
+ device->SetHWColorKey = DirectFB_SetHWColorKey;
+ device->SetHWAlpha = DirectFB_SetHWAlpha;
+ device->LockHWSurface = DirectFB_LockHWSurface;
+ device->UnlockHWSurface = DirectFB_UnlockHWSurface;
+ device->FlipHWSurface = DirectFB_FlipHWSurface;
+ device->FreeHWSurface = DirectFB_FreeHWSurface;
+ device->ShowWMCursor = DirectFB_ShowWMCursor;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = DirectFB_InitOSKeymap;
+ device->PumpEvents = DirectFB_PumpEvents;
+
+ device->free = DirectFB_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap DirectFB_bootstrap = {
+ "directfb", "DirectFB",
+ DirectFB_Available, DirectFB_CreateDevice
+};
+
+static DFBSurfacePixelFormat GetFormatForBpp (int bpp, IDirectFBDisplayLayer *layer)
+{
+ DFBDisplayLayerConfig dlc;
+ int bytes = (bpp + 7) / 8;
+
+ layer->GetConfiguration (layer, &dlc);
+
+ if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
+ return dlc.pixelformat;
+
+ switch (bytes)
+ {
+ case 1:
+ return DSPF_LUT8;
+ case 2:
+ return DSPF_RGB16;
+ case 3:
+ return DSPF_RGB24;
+ case 4:
+ return DSPF_RGB32;
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+static DFBEnumerationResult EnumModesCallback (int width,
+ int height,
+ int bpp,
+ void *data)
+{
+ SDL_VideoDevice *this = (SDL_VideoDevice *)data;
+ struct DirectFBEnumRect *enumrect;
+
+ HIDDEN->nummodes++;
+
+ if (enumlist && enumlist->r.w == width && enumlist->r.h == height)
+ return DFENUM_OK;
+
+ enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect));
+ if (!enumrect)
+ {
+ SDL_OutOfMemory();
+ return DFENUM_CANCEL;
+ }
+
+ enumrect->r.w = (Uint16)width;
+ enumrect->r.h = (Uint16)height;
+ enumrect->next = enumlist;
+
+ enumlist = enumrect;
+
+ return DFENUM_OK;
+}
+
+struct private_hwdata {
+ IDirectFBSurface *surface;
+ IDirectFBPalette *palette;
+};
+
+void SetDirectFBerror (const char *function, DFBResult code)
+{
+ const char *error = DirectFBErrorString (code);
+
+ if (error)
+ SDL_SetError("%s: %s", function, error);
+ else
+ SDL_SetError("Unknown error code from %s", function);
+}
+
+static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format)
+{
+ if (format->Rmask && format->Gmask && format->Bmask)
+ {
+ switch (format->BitsPerPixel)
+ {
+ case 8:
+ return DSPF_LUT8;
+
+ case 16:
+ if (format->Rmask == 0xF800 &&
+ format->Gmask == 0x07E0 &&
+ format->Bmask == 0x001F)
+ return DSPF_RGB16;
+ /* fall through */
+
+ case 15:
+ if (format->Rmask == 0x7C00 &&
+ format->Gmask == 0x03E0 &&
+ format->Bmask == 0x001F)
+ return DSPF_ARGB1555;
+ break;
+
+ case 24:
+ if (format->Rmask == 0xFF0000 &&
+ format->Gmask == 0x00FF00 &&
+ format->Bmask == 0x0000FF)
+ return DSPF_RGB24;
+ break;
+
+ case 32:
+ if (format->Rmask == 0xFF0000 &&
+ format->Gmask == 0x00FF00 &&
+ format->Bmask == 0x0000FF)
+ {
+ if (format->Amask == 0xFF000000)
+ return DSPF_ARGB;
+ else
+ return DSPF_RGB32;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (format->BitsPerPixel)
+ {
+ case 8:
+ return DSPF_LUT8;
+ case 15:
+ return DSPF_ARGB1555;
+ case 16:
+ return DSPF_RGB16;
+ case 24:
+ return DSPF_RGB24;
+ case 32:
+ return DSPF_RGB32;
+ }
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+static SDL_Palette *AllocatePalette(int size)
+{
+ SDL_Palette *palette;
+ SDL_Color *colors;
+
+ palette = SDL_calloc (1, sizeof(SDL_Palette));
+ if (!palette)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ colors = SDL_calloc (size, sizeof(SDL_Color));
+ if (!colors)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ palette->ncolors = size;
+ palette->colors = colors;
+
+ return palette;
+}
+
+static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
+{
+ format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
+ format->BitsPerPixel = format->BytesPerPixel = 0;
+
+ switch (pixelformat)
+ {
+ case DSPF_A8:
+ format->Amask = 0x000000FF;
+ break;
+
+ case DSPF_ARGB1555:
+ format->Rmask = 0x00007C00;
+ format->Gmask = 0x000003E0;
+ format->Bmask = 0x0000001F;
+ break;
+
+ case DSPF_RGB16:
+ format->Rmask = 0x0000F800;
+ format->Gmask = 0x000007E0;
+ format->Bmask = 0x0000001F;
+ break;
+
+ case DSPF_ARGB:
+ format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */
+ /* fall through */
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ format->Rmask = 0x00FF0000;
+ format->Gmask = 0x0000FF00;
+ format->Bmask = 0x000000FF;
+ break;
+
+ case DSPF_LUT8:
+ format->Rmask = 0x000000FF;
+ format->Gmask = 0x000000FF;
+ format->Bmask = 0x000000FF;
+
+ if (!format->palette)
+ format->palette = AllocatePalette(256);
+ break;
+
+ default:
+ fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat);
+ return -1;
+ }
+
+ format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
+ format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
+
+ return 0;
+}
+
+
+int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i;
+ DFBResult ret;
+#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
+ DFBCardCapabilities caps;
+#else
+ DFBGraphicsDeviceDescription caps;
+#endif
+ DFBDisplayLayerConfig dlc;
+ struct DirectFBEnumRect *rect;
+ IDirectFB *dfb = NULL;
+ IDirectFBDisplayLayer *layer = NULL;
+ IDirectFBEventBuffer *events = NULL;
+
+ HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL;
+ HIDDEN->enable_mga_crtc2 = 0;
+ HIDDEN->mga_crtc2_stretch_overscan = 1;
+
+ ret = DirectFBInit (NULL, NULL);
+ if (ret)
+ {
+ SetDirectFBerror ("DirectFBInit", ret);
+ goto error;
+ }
+
+ ret = DirectFBCreate (&dfb);
+ if (ret)
+ {
+ SetDirectFBerror ("DirectFBCreate", ret);
+ goto error;
+ }
+
+ ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->GetDisplayLayer", ret);
+ goto error;
+ }
+
+ ret = dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events);
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->CreateEventBuffer", ret);
+ goto error;
+ }
+
+ layer->EnableCursor (layer, 1);
+
+ /* Query layer configuration to determine the current mode and pixelformat */
+ layer->GetConfiguration (layer, &dlc);
+
+ /* If current format is not supported use LUT8 as the default */
+ if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
+ DFBToSDLPixelFormat (DSPF_LUT8, vformat);
+
+ /* Enumerate the available fullscreen modes */
+ ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->EnumVideoModes", ret);
+ goto error;
+ }
+
+ HIDDEN->modelist = SDL_calloc (HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
+ if (!HIDDEN->modelist)
+ {
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ for (i = 0, rect = enumlist; rect; ++i, rect = rect->next )
+ {
+ HIDDEN->modelist[i] = &rect->r;
+ }
+
+ HIDDEN->modelist[i] = NULL;
+
+
+ /* Query card capabilities to get the video memory size */
+#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
+ dfb->GetCardCapabilities (dfb, &caps);
+#else
+ dfb->GetDeviceDescription (dfb, &caps);
+#endif
+
+ this->info.wm_available = 1;
+ this->info.hw_available = 1;
+ this->info.blit_hw = 1;
+ this->info.blit_hw_CC = 1;
+ this->info.blit_hw_A = 1;
+ this->info.blit_fill = 1;
+ this->info.video_mem = caps.video_memory / 1024;
+ this->info.current_w = dlc.width;
+ this->info.current_h = dlc.height;
+
+ HIDDEN->initialized = 1;
+ HIDDEN->dfb = dfb;
+ HIDDEN->layer = layer;
+ HIDDEN->eventbuffer = events;
+
+ if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL)
+ HIDDEN->enable_mga_crtc2 = 1;
+
+ if (HIDDEN->enable_mga_crtc2)
+ {
+ DFBDisplayLayerConfig dlc;
+ DFBDisplayLayerConfigFlags failed;
+
+ ret = dfb->GetDisplayLayer (dfb, 2, &HIDDEN->c2layer);
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret);
+ goto error;
+ }
+
+ ret = HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, DLSCL_EXCLUSIVE);
+ if (ret)
+ {
+ SetDirectFBerror ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
+ goto error;
+ }
+
+ ret = HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, DLSCL_EXCLUSIVE);
+ if (ret)
+ {
+ SetDirectFBerror ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
+ goto error;
+ }
+
+ HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0);
+
+ /* Init the surface here as it got a fixed size */
+ dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
+ dlc.buffermode = DLBM_BACKVIDEO;
+ dlc.pixelformat = DSPF_RGB32;
+
+ ret = HIDDEN->c2layer->TestConfiguration( HIDDEN->c2layer, &dlc, &failed );
+ if (ret)
+ {
+ SetDirectFBerror ("c2layer->TestConfiguration", ret);
+ goto error;
+ }
+
+ ret = HIDDEN->c2layer->SetConfiguration( HIDDEN->c2layer, &dlc );
+ if (ret)
+ {
+ SetDirectFBerror ("c2layer->SetConfiguration", ret);
+ goto error;
+ }
+
+ ret = HIDDEN->c2layer->GetSurface( HIDDEN->c2layer, &HIDDEN->c2frame );
+ if (ret)
+ {
+ SetDirectFBerror ("c2layer->GetSurface", ret);
+ goto error;
+ }
+
+ HIDDEN->c2framesize.x = 0;
+ HIDDEN->c2framesize.y = 0;
+ HIDDEN->c2frame->GetSize( HIDDEN->c2frame, &HIDDEN->c2framesize.w, &HIDDEN->c2framesize.h);
+
+ HIDDEN->c2frame->SetBlittingFlags( HIDDEN->c2frame, DSBLIT_NOFX );
+ HIDDEN->c2frame->SetColor( HIDDEN->c2frame, 0, 0, 0, 0xff );
+
+ /* Clear CRTC2 */
+ HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
+ HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
+ HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
+ HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
+ HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
+
+ HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF );
+
+ /* Check if overscan is possibly set */
+ if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL)
+ {
+ float overscan = 0;
+ if (SDL_sscanf(SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", &overscan) == 1)
+ if (overscan > 0 && overscan < 2)
+ HIDDEN->mga_crtc2_stretch_overscan = overscan;
+ }
+
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan);
+ #endif
+ }
+
+ return 0;
+
+ error:
+ if (events)
+ events->Release (events);
+
+ if (HIDDEN->c2frame)
+ HIDDEN->c2frame->Release (HIDDEN->c2frame);
+
+ if (HIDDEN->c2layer)
+ HIDDEN->c2layer->Release (HIDDEN->c2layer);
+
+ if (layer)
+ layer->Release (layer);
+
+ if (dfb)
+ dfb->Release (dfb);
+
+ return -1;
+}
+
+static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ return HIDDEN->modelist;
+ else
+ if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
+ return (SDL_Rect**) -1;
+
+ return NULL;
+}
+
+static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
+{
+ DFBResult ret;
+ DFBSurfaceDescription dsc;
+ DFBSurfacePixelFormat pixelformat;
+ IDirectFBSurface *surface;
+
+ fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
+ width, height, bpp, flags);
+
+ flags |= SDL_FULLSCREEN;
+
+ /* Release previous primary surface */
+ if (current->hwdata && current->hwdata->surface)
+ {
+ current->hwdata->surface->Release (current->hwdata->surface);
+ current->hwdata->surface = NULL;
+
+ /* And its palette if present */
+ if (current->hwdata->palette)
+ {
+ current->hwdata->palette->Release (current->hwdata->palette);
+ current->hwdata->palette = NULL;
+ }
+ }
+ else if (!current->hwdata)
+ {
+ /* Allocate the hardware acceleration data */
+ current->hwdata = (struct private_hwdata *) SDL_calloc (1, sizeof(*current->hwdata));
+ if (!current->hwdata)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ }
+
+ /* Set cooperative level depending on flag SDL_FULLSCREEN */
+ if (flags & SDL_FULLSCREEN)
+ {
+ ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
+ if (ret && !HIDDEN->enable_mga_crtc2)
+ {
+ DirectFBError ("dfb->SetCooperativeLevel", ret);
+ flags &= ~SDL_FULLSCREEN;
+ }
+ }
+ else
+ HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
+
+ /* Set video mode */
+ ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
+ if (ret)
+ {
+ if (flags & SDL_FULLSCREEN)
+ {
+ flags &= ~SDL_FULLSCREEN;
+ HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
+ ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
+ }
+
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->SetVideoMode", ret);
+ return NULL;
+ }
+ }
+
+ /* Create primary surface */
+ dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
+ dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
+ dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
+
+ ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
+ if (ret && (flags & SDL_DOUBLEBUF))
+ {
+ /* Try without double buffering */
+ dsc.caps &= ~DSCAPS_FLIPPING;
+ ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
+ }
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->CreateSurface", ret);
+ return NULL;
+ }
+
+ current->w = width;
+ current->h = height;
+ current->flags = SDL_HWSURFACE | SDL_PREALLOC;
+
+ if (flags & SDL_FULLSCREEN)
+ {
+ current->flags |= SDL_FULLSCREEN;
+ this->UpdateRects = DirectFB_DirectUpdate;
+ }
+ else
+ this->UpdateRects = DirectFB_WindowedUpdate;
+
+ if (dsc.caps & DSCAPS_FLIPPING)
+ current->flags |= SDL_DOUBLEBUF;
+
+ surface->GetPixelFormat (surface, &pixelformat);
+
+ DFBToSDLPixelFormat (pixelformat, current->format);
+
+ /* Get the surface palette (if supported) */
+ if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat ))
+ {
+ surface->GetPalette (surface, &current->hwdata->palette);
+
+ current->flags |= SDL_HWPALETTE;
+ }
+
+ current->hwdata->surface = surface;
+
+ /* MGA CRTC2 stuff */
+ if (HIDDEN->enable_mga_crtc2)
+ {
+ /* no stretching if c2ssize == c2framesize */
+ HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
+ HIDDEN->c2ssize.w = width;
+ HIDDEN->c2ssize.h = height;
+
+ HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
+ HIDDEN->c2dsize.w = width;
+ HIDDEN->c2dsize.h = height;
+
+ HIDDEN->mga_crtc2_stretch = 0;
+
+ if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL)
+ {
+ /* Normally assume a picture aspect ratio of 4:3 */
+ int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j;
+
+ for (i = 1; i < 20; i++)
+ {
+ for (j = 1; j < 10; j++)
+ {
+ if ((float)width/(float)i*(float)j == height)
+ {
+ zoom_aspect_x = i;
+ zoom_aspect_y = j;
+
+ /* break the loop */
+ i = 21;
+ break;
+ }
+ }
+ }
+
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n", width, height, zoom_aspect_x, zoom_aspect_y);
+ printf("CRTC2 resolution: X: %d, Y: %d\n", HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
+ #endif
+
+ /* don't stretch only slightly smaller/larger images */
+ if ((float)width < (float)HIDDEN->c2framesize.w*0.95 || (float)height < (float)HIDDEN->c2framesize.h*0.95)
+ {
+ while ((float)HIDDEN->c2dsize.w < (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan && (float)HIDDEN->c2dsize.h < (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
+ {
+ HIDDEN->c2dsize.w+=zoom_aspect_x;
+ HIDDEN->c2dsize.h+=zoom_aspect_y;
+ }
+
+ /* one step down */
+ HIDDEN->c2dsize.w-=zoom_aspect_x;
+ HIDDEN->c2dsize.h-=zoom_aspect_y;
+
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
+ #endif
+
+ HIDDEN->mga_crtc2_stretch = 1;
+ }
+ else if ((float)width > (float)HIDDEN->c2framesize.w*0.95 || (float)height > (float)HIDDEN->c2framesize.h*0.95)
+ {
+ while ((float)HIDDEN->c2dsize.w > (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan || (float)HIDDEN->c2dsize.h > (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
+ {
+ HIDDEN->c2dsize.w-=zoom_aspect_x;
+ HIDDEN->c2dsize.h-=zoom_aspect_y;
+ }
+
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("Down-Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
+ #endif
+
+ HIDDEN->mga_crtc2_stretch = 1;
+ } else {
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("Not stretching image\n");
+ #endif
+ }
+
+ /* Panning */
+ if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
+ HIDDEN->c2dsize.x = (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2;
+ else
+ HIDDEN->c2dsize.x = (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2;
+
+ if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
+ HIDDEN->c2dsize.y = (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2;
+ else
+ HIDDEN->c2dsize.y = (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2;
+
+ #ifdef DIRECTFB_CRTC2_DEBUG
+ printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
+ #endif
+ }
+ }
+
+ return current;
+}
+
+static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ DFBResult ret;
+ DFBSurfaceDescription dsc;
+
+ /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
+ surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
+
+ if (surface->w < 8 || surface->h < 8)
+ return -1;
+
+ /* fill surface description */
+ dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
+ dsc.width = surface->w;
+ dsc.height = surface->h;
+ dsc.caps = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
+
+ /* find the right pixelformat */
+ dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
+ if (dsc.pixelformat == DSPF_UNKNOWN)
+ return -1;
+
+ /* Allocate the hardware acceleration data */
+ surface->hwdata = (struct private_hwdata *) SDL_calloc (1, sizeof(*surface->hwdata));
+ if (surface->hwdata == NULL)
+ {
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ /* Create the surface */
+ ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface);
+ if (ret)
+ {
+ SetDirectFBerror ("dfb->CreateSurface", ret);
+ free (surface->hwdata);
+ surface->hwdata = NULL;
+ return -1;
+ }
+
+ surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
+
+ return 0;
+}
+
+static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (surface->hwdata && HIDDEN->initialized)
+ {
+ surface->hwdata->surface->Release (surface->hwdata->surface);
+ free (surface->hwdata);
+ surface->hwdata = NULL;
+ }
+}
+
+static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
+ src->hwdata, dst->hwdata);*/
+
+ if (!src->hwdata || !dst->hwdata)
+ return 0;
+
+ src->flags |= SDL_HWACCEL;
+ src->map->hw_blit = DirectFB_HWAccelBlit;
+
+ return 1;
+}
+
+static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
+
+ DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
+ DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
+
+ IDirectFBSurface *surface = dst->hwdata->surface;
+
+ if (src->flags & SDL_SRCCOLORKEY)
+ {
+ flags |= DSBLIT_SRC_COLORKEY;
+ DirectFB_SetHWColorKey (NULL, src, src->format->colorkey);
+ }
+
+ if (src->flags & SDL_SRCALPHA)
+ {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+ surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
+ }
+
+ surface->SetBlittingFlags (surface, flags);
+
+ if (sr.w == dr.w && sr.h == dr.h)
+ surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
+ else
+ surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
+
+ return 0;
+}
+
+static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
+{
+ SDL_PixelFormat *fmt = dst->format;
+ IDirectFBSurface *surface = dst->hwdata->surface;
+
+ /* ugly */
+ surface->SetColor (surface,
+ (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
+ (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
+ (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF);
+ surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h);
+
+ return 0;
+}
+
+static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key)
+{
+ SDL_PixelFormat *fmt = src->format;
+ IDirectFBSurface *surface = src->hwdata->surface;
+
+ if (fmt->BitsPerPixel == 8)
+ surface->SetSrcColorKeyIndex (surface, key);
+ else
+ /* ugly */
+ surface->SetSrcColorKey (surface,
+ (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
+ (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
+ (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift));
+
+ return 0;
+}
+
+static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
+{
+ return 0;
+}
+
+static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (HIDDEN->enable_mga_crtc2)
+ {
+ int rtn = surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, 0);
+ if (HIDDEN->mga_crtc2_stretch)
+ HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
+ else
+ HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
+
+ HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
+ return rtn;
+ }
+ else
+ return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
+}
+
+static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ DFBResult ret;
+ void *data;
+ int pitch;
+
+ ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
+ DSLF_WRITE, &data, &pitch);
+ if (ret)
+ {
+ SetDirectFBerror ("surface->Lock", ret);
+ return -1;
+ }
+
+ surface->pixels = data;
+ surface->pitch = pitch;
+
+ return 0;
+}
+
+static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ surface->hwdata->surface->Unlock (surface->hwdata->surface);
+ surface->pixels = NULL;
+}
+
+static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ if (HIDDEN->enable_mga_crtc2)
+ {
+ if (HIDDEN->mga_crtc2_stretch)
+ HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, this->screen->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
+ else
+ HIDDEN->c2frame->Blit(HIDDEN->c2frame, this->screen->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
+
+ HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
+ }
+}
+
+static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ DFBRegion region;
+ int i;
+ int region_valid = 0;
+ IDirectFBSurface *surface = this->screen->hwdata->surface;
+
+ for (i=0; i<numrects; ++i)
+ {
+ int x2, y2;
+
+ if ( ! rects[i].w ) /* Clipped? */
+ continue;
+
+ x2 = rects[i].x + rects[i].w - 1;
+ y2 = rects[i].y + rects[i].h - 1;
+
+ if (region_valid)
+ {
+ if (rects[i].x < region.x1)
+ region.x1 = rects[i].x;
+
+ if (rects[i].y < region.y1)
+ region.y1 = rects[i].y;
+
+ if (x2 > region.x2)
+ region.x2 = x2;
+
+ if (y2 > region.y2)
+ region.y2 = y2;
+ }
+ else
+ {
+ region.x1 = rects[i].x;
+ region.y1 = rects[i].y;
+ region.x2 = x2;
+ region.y2 = y2;
+
+ region_valid = 1;
+ }
+ }
+
+ if (region_valid)
+ {
+ if (HIDDEN->enable_mga_crtc2)
+ {
+ if (HIDDEN->mga_crtc2_stretch)
+ HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
+ else
+ HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
+
+ HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
+ }
+ else
+ surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
+ }
+}
+
+int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ IDirectFBPalette *palette = this->screen->hwdata->palette;
+
+ if (!palette)
+ return 0;
+
+ if (firstcolor > 255)
+ return 0;
+
+ if (firstcolor + ncolors > 256)
+ ncolors = 256 - firstcolor;
+
+ if (ncolors > 0)
+ {
+ int i;
+ DFBColor entries[ncolors];
+
+ for (i=0; i<ncolors; i++)
+ {
+ entries[i].a = 0xff;
+ entries[i].r = colors[i].r;
+ entries[i].g = colors[i].g;
+ entries[i].b = colors[i].b;
+ }
+
+ palette->SetEntries (palette, entries, ncolors, firstcolor);
+ }
+
+ return 1;
+}
+
+void DirectFB_VideoQuit(_THIS)
+{
+ struct DirectFBEnumRect *rect = enumlist;
+
+ if (this->screen && this->screen->hwdata)
+ {
+ IDirectFBSurface *surface = this->screen->hwdata->surface;
+ IDirectFBPalette *palette = this->screen->hwdata->palette;
+
+ if (palette)
+ palette->Release (palette);
+
+ if (surface)
+ surface->Release (surface);
+
+ this->screen->hwdata->surface = NULL;
+ this->screen->hwdata->palette = NULL;
+ }
+
+ if (HIDDEN->c2frame)
+ {
+ HIDDEN->c2frame->Release (HIDDEN->c2frame);
+ HIDDEN->c2frame = NULL;
+ }
+
+ if (HIDDEN->eventbuffer)
+ {
+ HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
+ HIDDEN->eventbuffer = NULL;
+ }
+
+ if (HIDDEN->c2layer)
+ {
+ HIDDEN->c2layer->Release (HIDDEN->c2layer);
+ HIDDEN->c2layer = NULL;
+ }
+
+ if (HIDDEN->layer)
+ {
+ HIDDEN->layer->Release (HIDDEN->layer);
+ HIDDEN->layer = NULL;
+ }
+
+ if (HIDDEN->dfb)
+ {
+ HIDDEN->dfb->Release (HIDDEN->dfb);
+ HIDDEN->dfb = NULL;
+ }
+
+ /* Free video mode list */
+ if (HIDDEN->modelist)
+ {
+ free (HIDDEN->modelist);
+ HIDDEN->modelist = NULL;
+ }
+
+ /* Free mode enumeration list */
+ while (rect)
+ {
+ struct DirectFBEnumRect *next = rect->next;
+ free (rect);
+ rect = next;
+ }
+ enumlist = NULL;
+
+ HIDDEN->initialized = 0;
+}
+
+
+int DirectFB_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ /* We can only hide or show the default cursor */
+ if ( cursor == NULL )
+ {
+ HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0x00);
+ }
+ else
+ {
+ HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0xFF);
+ }
+ return 1;
+}
+
+void DirectFB_FinalQuit(void)
+{
+}
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.h b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.h
new file mode 100644
index 0000000..e1fa12c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_video.h
@@ -0,0 +1,62 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_DirectFB_video_h
+#define _SDL_DirectFB_video_h
+
+#include <directfb.h>
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+#define _THIS SDL_VideoDevice *this
+
+/* Private display data */
+
+struct SDL_PrivateVideoData
+{
+ int initialized;
+
+ IDirectFB *dfb;
+ IDirectFBDisplayLayer *layer;
+ IDirectFBEventBuffer *eventbuffer;
+
+ int nummodes;
+ SDL_Rect **modelist;
+
+ /* MGA CRTC2 support */
+ int enable_mga_crtc2;
+ int mga_crtc2_stretch;
+ float mga_crtc2_stretch_overscan;
+ IDirectFBDisplayLayer *c2layer;
+ IDirectFBSurface *c2frame;
+ DFBRectangle c2ssize; /* Real screen size */
+ DFBRectangle c2dsize; /* Stretched screen size */
+ DFBRectangle c2framesize; /* CRTC2 screen size */
+};
+
+#define HIDDEN (this->hidden)
+
+void SetDirectFBerror (const char *function, DFBResult code);
+
+#endif /* _SDL_DirectFB_video_h */
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.c b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.c
new file mode 100644
index 0000000..fd0cef1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.c
@@ -0,0 +1,290 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the DirectFB implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_DirectFB_yuv.h"
+#include "../SDL_yuvfuncs.h"
+
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs directfb_yuvfuncs = {
+ DirectFB_LockYUVOverlay,
+ DirectFB_UnlockYUVOverlay,
+ DirectFB_DisplayYUVOverlay,
+ DirectFB_FreeYUVOverlay
+};
+
+struct private_yuvhwdata {
+ DFBDisplayLayerID layer_id;
+
+ IDirectFBDisplayLayer *layer;
+ IDirectFBSurface *surface;
+
+ /* These are just so we don't have to allocate them separately */
+ Uint16 pitches[3];
+ Uint8 *planes[3];
+};
+
+static DFBEnumerationResult
+enum_layers_callback( DFBDisplayLayerID id,
+ DFBDisplayLayerDescription desc,
+ void *data )
+{
+ struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
+
+ /* we don't want the primary */
+ if (id == DLID_PRIMARY)
+ return DFENUM_OK;
+
+ /* take the one with a surface for video */
+ if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO))
+ {
+ hwdata->layer_id = id;
+
+ return DFENUM_CANCEL;
+ }
+
+ return DFENUM_OK;
+}
+
+
+static DFBResult CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
+ int width, int height, Uint32 format)
+{
+ DFBResult ret;
+ IDirectFB *dfb = HIDDEN->dfb;
+ IDirectFBDisplayLayer *layer;
+ DFBDisplayLayerConfig conf;
+
+ ret = dfb->EnumDisplayLayers (dfb, enum_layers_callback, hwdata);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
+ return ret;
+ }
+
+ if (!hwdata->layer_id)
+ return DFB_UNSUPPORTED;
+
+ ret = dfb->GetDisplayLayer (dfb, hwdata->layer_id, &layer);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
+ return ret;
+ }
+
+ conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
+ conf.width = width;
+ conf.height = height;
+
+ switch (format)
+ {
+ case SDL_YV12_OVERLAY:
+ conf.pixelformat = DSPF_YV12;
+ break;
+ case SDL_IYUV_OVERLAY:
+ conf.pixelformat = DSPF_I420;
+ break;
+ case SDL_YUY2_OVERLAY:
+ conf.pixelformat = DSPF_YUY2;
+ break;
+ case SDL_UYVY_OVERLAY:
+ conf.pixelformat = DSPF_UYVY;
+ break;
+ default:
+ fprintf (stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", format);
+ break;
+ }
+
+ /* Need to set coop level or newer DirectFB versions will fail here. */
+ ret = layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret);
+ layer->Release (layer);
+ return ret;
+ }
+
+ ret = layer->SetConfiguration (layer, &conf);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
+ layer->Release (layer);
+ return ret;
+ }
+
+ ret = layer->GetSurface (layer, &hwdata->surface);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
+ layer->Release (layer);
+ return ret;
+ }
+
+ hwdata->layer = layer;
+
+ return DFB_OK;
+}
+
+SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+ SDL_Overlay *overlay;
+ struct private_yuvhwdata *hwdata;
+
+ /* Create the overlay structure */
+ overlay = SDL_calloc (1, sizeof(SDL_Overlay));
+ if (!overlay)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &directfb_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
+ overlay->hwdata = hwdata;
+ if (!hwdata)
+ {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay (overlay);
+ return NULL;
+ }
+
+ if (CreateYUVSurface (this, hwdata, width, height, format))
+ {
+ SDL_FreeYUVOverlay (overlay);
+ return NULL;
+ }
+
+ overlay->hw_overlay = 1;
+
+ /* Set up the plane pointers */
+ overlay->pitches = hwdata->pitches;
+ overlay->pixels = hwdata->planes;
+ switch (format)
+ {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ overlay->planes = 3;
+ break;
+ default:
+ overlay->planes = 1;
+ break;
+ }
+
+ /* We're all done.. */
+ return overlay;
+}
+
+int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ DFBResult ret;
+ void *data;
+ int pitch;
+ IDirectFBSurface *surface = overlay->hwdata->surface;
+
+ ret = surface->Lock (surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFBSurface::Lock", ret);
+ return -1;
+ }
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->pitches[0] = (Uint16) pitch;
+ overlay->pixels[0] = (Uint8*) data;
+
+ switch (overlay->format)
+ {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ /* Add the two extra planes */
+ overlay->pitches[1] = overlay->pitches[0] / 2;
+ overlay->pitches[2] = overlay->pitches[0] / 2;
+ overlay->pixels[1] = overlay->pixels[0] + overlay->pitches[0] * overlay->h;
+ overlay->pixels[2] = overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
+ break;
+ default:
+ /* Only one plane, no worries */
+ break;
+ }
+
+ return 0;
+}
+
+void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ IDirectFBSurface *surface = overlay->hwdata->surface;
+
+ overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
+
+ surface->Unlock (surface);
+}
+
+int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
+{
+ DFBResult ret;
+ DFBDisplayLayerConfig conf;
+ IDirectFBDisplayLayer *primary = HIDDEN->layer;
+ IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
+
+ primary->GetConfiguration (primary, &conf);
+
+ ret = layer->SetScreenLocation (layer,
+ dst->x / (float) conf.width, dst->y / (float) conf.height,
+ dst->w / (float) conf.width, dst->h / (float) conf.height );
+ if (ret)
+ {
+ SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ struct private_yuvhwdata *hwdata;
+
+ hwdata = overlay->hwdata;
+ if (hwdata)
+ {
+ if (hwdata->surface)
+ hwdata->surface->Release (hwdata->surface);
+
+ if (hwdata->layer)
+ hwdata->layer->Release (hwdata->layer);
+
+ free (hwdata);
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.h b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.h
new file mode 100644
index 0000000..64bc86f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/directfb/SDL_DirectFB_yuv.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the DirectFB implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_DirectFB_video.h"
+
+extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+
+extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
+
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents.c b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents.c
new file mode 100644
index 0000000..177fc3f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents.c
@@ -0,0 +1,45 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Being a null driver, there's no event stream. We just define stubs for
+ most of the API. */
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nullvideo.h"
+#include "SDL_nullevents_c.h"
+
+void DUMMY_PumpEvents(_THIS)
+{
+ /* do nothing. */
+}
+
+void DUMMY_InitOSKeymap(_THIS)
+{
+ /* do nothing. */
+}
+
+/* end of SDL_nullevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents_c.h b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents_c.h
new file mode 100644
index 0000000..3b65794
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullevents_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_nullvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void DUMMY_InitOSKeymap(_THIS);
+extern void DUMMY_PumpEvents(_THIS);
+
+/* end of SDL_nullevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse.c b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse.c
new file mode 100644
index 0000000..47daea8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse.c
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nullmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse_c.h b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse_c.h
new file mode 100644
index 0000000..479eb0e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullmouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_nullvideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.c b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.c
new file mode 100644
index 0000000..7e096e2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.c
@@ -0,0 +1,239 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Dummy SDL video driver implementation; this is just enough to make an
+ * SDL-based application THINK it's got a working video driver, for
+ * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it,
+ * and also for use as a collection of stubs when porting SDL to a new
+ * platform for which you haven't yet written a valid video driver.
+ *
+ * This is also a great way to determine bottlenecks: if you think that SDL
+ * is a performance problem for a given platform, enable this driver, and
+ * then see if your application runs faster without video overhead.
+ *
+ * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion
+ * of this was cut-and-pasted from Stephane Peter's work in the AAlib
+ * SDL video driver. Renamed to "DUMMY" by Sam Lantinga.
+ */
+
+#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_nullvideo.h"
+#include "SDL_nullevents_c.h"
+#include "SDL_nullmouse_c.h"
+
+#define DUMMYVID_DRIVER_NAME "dummy"
+
+/* Initialization/Query functions */
+static int DUMMY_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DUMMY_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DUMMY_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DUMMY_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void DUMMY_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DUMMY_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DUMMY_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DUMMY_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DUMMY_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* etc. */
+static void DUMMY_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+/* DUMMY driver bootstrap functions */
+
+static int DUMMY_Available(void)
+{
+ const char *envr = SDL_getenv("SDL_VIDEODRIVER");
+ if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) {
+ return(1);
+ }
+
+ return(0);
+}
+
+static void DUMMY_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *DUMMY_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = DUMMY_VideoInit;
+ device->ListModes = DUMMY_ListModes;
+ device->SetVideoMode = DUMMY_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = DUMMY_SetColors;
+ device->UpdateRects = DUMMY_UpdateRects;
+ device->VideoQuit = DUMMY_VideoQuit;
+ device->AllocHWSurface = DUMMY_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = DUMMY_LockHWSurface;
+ device->UnlockHWSurface = DUMMY_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = DUMMY_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = DUMMY_InitOSKeymap;
+ device->PumpEvents = DUMMY_PumpEvents;
+
+ device->free = DUMMY_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap DUMMY_bootstrap = {
+ DUMMYVID_DRIVER_NAME, "SDL dummy video driver",
+ DUMMY_Available, DUMMY_CreateDevice
+};
+
+
+int DUMMY_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ /*
+ fprintf(stderr, "WARNING: You are using the SDL dummy video driver!\n");
+ */
+
+ /* Determine the screen depth (use default 8-bit depth) */
+ /* we change this during the SDL_SetVideoMode implementation... */
+ vformat->BitsPerPixel = 8;
+ vformat->BytesPerPixel = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **DUMMY_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return (SDL_Rect **) -1;
+}
+
+SDL_Surface *DUMMY_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if ( this->hidden->buffer ) {
+ SDL_free( this->hidden->buffer );
+ }
+
+ this->hidden->buffer = SDL_malloc(width * height * (bpp / 8));
+ if ( ! this->hidden->buffer ) {
+ SDL_SetError("Couldn't allocate buffer for requested mode");
+ return(NULL);
+ }
+
+/* printf("Setting mode %dx%d\n", width, height); */
+
+ SDL_memset(this->hidden->buffer, 0, width * height * (bpp / 8));
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
+ SDL_free(this->hidden->buffer);
+ this->hidden->buffer = NULL;
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = flags & SDL_FULLSCREEN;
+ this->hidden->w = current->w = width;
+ this->hidden->h = current->h = height;
+ current->pitch = current->w * (bpp / 8);
+ current->pixels = this->hidden->buffer;
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int DUMMY_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void DUMMY_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int DUMMY_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void DUMMY_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void DUMMY_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ /* do nothing. */
+}
+
+int DUMMY_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ /* do nothing of note. */
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void DUMMY_VideoQuit(_THIS)
+{
+ if (this->screen->pixels != NULL)
+ {
+ SDL_free(this->screen->pixels);
+ this->screen->pixels = NULL;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.h b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.h
new file mode 100644
index 0000000..05c19e3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/dummy/SDL_nullvideo.h
@@ -0,0 +1,40 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_nullvideo_h
+#define _SDL_nullvideo_h
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ int w, h;
+ void *buffer;
+};
+
+#endif /* _SDL_nullvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/e_log.h b/distrib/sdl-1.2.15/src/video/e_log.h
new file mode 100644
index 0000000..7f8bf71
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/e_log.h
@@ -0,0 +1,140 @@
+/* @(#)e_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: e_log.c,v 1.8 1995/05/10 20:45:49 jtc Exp $";
+#endif
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k*ln2 + log(1+f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log(x) is NaN with signal if x < 0 (including -INF) ;
+ * log(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+/*#include "math.h"*/
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+ double __ieee754_log(double x)
+#else
+ double __ieee754_log(x)
+ double x;
+#endif
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if(f==zero) {if(k==0) return zero; else {dk=(double)k;
+ return dk*ln2_hi+dk*ln2_lo;}
+ }
+ R = f*f*(0.5-0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(double)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/(2.0+f);
+ dk = (double)k;
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/e_pow.h b/distrib/sdl-1.2.15/src/video/e_pow.h
new file mode 100644
index 0000000..0aa372a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/e_pow.h
@@ -0,0 +1,302 @@
+/* @(#)e_pow.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $";
+#endif
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 53-24 = 29 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating muti-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ * pow(x,y) returns x**y nearly rounded. In particular
+ * pow(integer,integer)
+ * always returns the correct integer provided it is
+ * representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+/*#include "math.h"*/
+#include "math_private.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+#ifdef __STDC__
+ double __ieee754_pow(double x, double y)
+#else
+ double __ieee754_pow(x,y)
+ double x, y;
+#endif
+{
+ double z,ax,z_h,z_l,p_h,p_l;
+ double y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy;
+ u_int32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if((iy|ly)==0) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+ iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x43400000) yisint = 2; /* even integer y */
+ else if(iy>=0x3ff00000) {
+ k = (iy>>20)-0x3ff; /* exponent */
+ if(k>20) {
+ j = ly>>(52-k);
+ if((u_int32_t)(j<<(52-k))==ly) yisint = 2-(j&1);
+ } else if(ly==0) {
+ j = iy>>(20-k);
+ if((j<<(20-k))==iy) yisint = 2-(j&1);
+ }
+ }
+ }
+
+ /* special value of y */
+ if(ly==0) {
+ if (iy==0x7ff00000) { /* y is +-inf */
+ if(((ix-0x3ff00000)|lx)==0)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3ff00000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ if(hy==0x40000000) return x*x; /* y is 2 */
+ if(hy==0x3fe00000) { /* y is 0.5 */
+ if(hx>=0) /* x >= +0 */
+ return __ieee754_sqrt(x);
+ }
+ }
+
+ ax = x < 0 ? -x : x; /*fabs(x);*/
+ /* special value of x */
+ if(lx==0) {
+ if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3ff00000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
+
+ /* |y| is huge */
+ if(iy>0x41e00000) { /* if |y| > 2**31 */
+ if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
+ if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = x-1; /* t has 20 trailing zeros */
+ w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ SET_LOW_WORD(t1,0);
+ t2 = v-(t1-u);
+ } else {
+ double s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00100000)
+ {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
+ n += ((ix)>>20)-0x3ff;
+ j = ix&0x000fffff;
+ /* determine interval */
+ ix = j|0x3ff00000; /* normalize ix */
+ if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00100000;}
+ SET_HIGH_WORD(ax,ix);
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ s = u*v;
+ s_h = s;
+ SET_LOW_WORD(s_h,0);
+ /* t_h=ax+bp[k] High */
+ t_h = zero;
+ SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = s*s;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+s);
+ s2 = s_h*s_h;
+ t_h = 3.0+s2+r;
+ SET_LOW_WORD(t_h,0);
+ t_l = r-((t_h-3.0)-s2);
+ /* u+v = s*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u+v;
+ SET_LOW_WORD(p_h,0);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (double)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ SET_LOW_WORD(t1,0);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0)
+ s = -one;/* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ SET_LOW_WORD(y1,0);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ EXTRACT_WORDS(j,i,z);
+ if (j>=0x40900000) { /* z >= 1024 */
+ if(((j-0x40900000)|i)!=0) /* if z > 1024 */
+ return s*huge*huge; /* overflow */
+ else {
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
+ if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
+ return s*tiny*tiny; /* underflow */
+ else {
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>20)-0x3ff;
+ n = 0;
+ if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00100000>>(k+1));
+ k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
+ t = zero;
+ SET_HIGH_WORD(t,n&~(0x000fffff>>k));
+ n = ((n&0x000fffff)|0x00100000)>>(20-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ SET_LOW_WORD(t,0);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_HIGH_WORD(j,z);
+ j += (n<<20);
+ if((j>>20)<=0) z = SDL_NAME(scalbn)(z,n); /* subnormal output */
+ else SET_HIGH_WORD(z,j);
+ return s*z;
+}
diff --git a/distrib/sdl-1.2.15/src/video/e_sqrt.h b/distrib/sdl-1.2.15/src/video/e_sqrt.h
new file mode 100644
index 0000000..657380e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/e_sqrt.h
@@ -0,0 +1,493 @@
+/* @(#)e_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $";
+#endif
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ * ------------------------------------------
+ * | Use the hardware sqrt if you have one |
+ * ------------------------------------------
+ * Method:
+ * Bit by bit method using integer arithmetic. (Slow, but portable)
+ * 1. Normalization
+ * Scale x to y in [1,4) with even powers of 2:
+ * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
+ * sqrt(x) = 2^k * sqrt(y)
+ * 2. Bit by bit computation
+ * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+ * i 0
+ * i+1 2
+ * s = 2*q , and y = 2 * ( y - q ). (1)
+ * i i i i
+ *
+ * To compute q from q , one checks whether
+ * i+1 i
+ *
+ * -(i+1) 2
+ * (q + 2 ) <= y. (2)
+ * i
+ * -(i+1)
+ * If (2) is false, then q = q ; otherwise q = q + 2 .
+ * i+1 i i+1 i
+ *
+ * With some algebric manipulation, it is not difficult to see
+ * that (2) is equivalent to
+ * -(i+1)
+ * s + 2 <= y (3)
+ * i i
+ *
+ * The advantage of (3) is that s and y can be computed by
+ * i i
+ * the following recurrence formula:
+ * if (3) is false
+ *
+ * s = s , y = y ; (4)
+ * i+1 i i+1 i
+ *
+ * otherwise,
+ * -i -(i+1)
+ * s = s + 2 , y = y - s - 2 (5)
+ * i+1 i i+1 i i
+ *
+ * One may easily use induction to prove (4) and (5).
+ * Note. Since the left hand side of (3) contain only i+2 bits,
+ * it does not necessary to do a full (53-bit) comparison
+ * in (3).
+ * 3. Final rounding
+ * After generating the 53 bits result, we compute one more bit.
+ * Together with the remainder, we can decide whether the
+ * result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ * (it will never equal to 1/2ulp).
+ * The rounding mode can be detected by checking whether
+ * huge + tiny is equal to huge, and whether huge - tiny is
+ * equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ * sqrt(+-0) = +-0 ... exact
+ * sqrt(inf) = inf
+ * sqrt(-ve) = NaN ... with invalid signal
+ * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+/*#include "math.h"*/
+#include "math_private.h"
+
+#ifdef __STDC__
+ double SDL_NAME(copysign)(double x, double y)
+#else
+ double SDL_NAME(copysign)(x,y)
+ double x,y;
+#endif
+{
+ u_int32_t hx,hy;
+ GET_HIGH_WORD(hx,x);
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+ return x;
+}
+
+#ifdef __STDC__
+ double SDL_NAME(scalbn) (double x, int n)
+#else
+ double SDL_NAME(scalbn) (x,n)
+ double x; int n;
+#endif
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ if (n< -50000) return tiny*x; /*underflow*/
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (k > 0x7fe) return huge*SDL_NAME(copysign)(huge,x); /* overflow */
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54) {
+ if (n > 50000) /* in case integer overflow in n+k */
+ return huge*SDL_NAME(copysign)(huge,x); /*overflow*/
+ else return tiny*SDL_NAME(copysign)(tiny,x); /*underflow*/
+ }
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
+
+#ifdef __STDC__
+ double __ieee754_sqrt(double x)
+#else
+ double __ieee754_sqrt(x)
+ double x;
+#endif
+{
+ double z;
+ int32_t sign = (int)0x80000000;
+ int32_t ix0,s0,q,m,t,i;
+ u_int32_t r,t1,s1,ix1,q1;
+
+ EXTRACT_WORDS(ix0,ix1,x);
+
+ /* take care of Inf and NaN */
+ if((ix0&0x7ff00000)==0x7ff00000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix0<=0) {
+ if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix0<0)
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ /* normalize x */
+ m = (ix0>>20);
+ if(m==0) { /* subnormal x */
+ while(ix0==0) {
+ m -= 21;
+ ix0 |= (ix1>>11); ix1 <<= 21;
+ }
+ for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+ m -= i-1;
+ ix0 |= (ix1>>(32-i));
+ ix1 <<= i;
+ }
+ m -= 1023; /* unbias exponent */
+ ix0 = (ix0&0x000fffff)|0x00100000;
+ if(m&1){ /* odd m, double x to make it even */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ }
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
+ r = 0x00200000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s0+r;
+ if(t<=ix0) {
+ s0 = t+r;
+ ix0 -= t;
+ q += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ r = sign;
+ while(r!=0) {
+ t1 = s1+r;
+ t = s0;
+ if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
+ s1 = t1+r;
+ if(((int32_t)(t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
+ ix0 -= t;
+ if (ix1 < t1) ix0 -= 1;
+ ix1 -= t1;
+ q1 += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if((ix0|ix1)!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
+ else if (z>one) {
+ if (q1==(u_int32_t)0xfffffffe) q+=1;
+ q1+=2;
+ } else
+ q1 += (q1&1);
+ }
+ }
+ ix0 = (q>>1)+0x3fe00000;
+ ix1 = q1>>1;
+ if ((q&1)==1) ix1 |= sign;
+ ix0 += (m <<20);
+ INSERT_WORDS(z,ix0,ix1);
+ return z;
+}
+
+/*
+Other methods (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan
+and K.C. Ng, written in May, 1986)
+
+ Two algorithms are given here to implement sqrt(x)
+ (IEEE double precision arithmetic) in software.
+ Both supply sqrt(x) correctly rounded. The first algorithm (in
+ Section A) uses newton iterations and involves four divisions.
+ The second one uses reciproot iterations to avoid division, but
+ requires more multiplications. Both algorithms need the ability
+ to chop results of arithmetic operations instead of round them,
+ and the INEXACT flag to indicate when an arithmetic operation
+ is executed exactly with no roundoff error, all part of the
+ standard (IEEE 754-1985). The ability to perform shift, add,
+ subtract and logical AND operations upon 32-bit words is needed
+ too, though not part of the standard.
+
+A. sqrt(x) by Newton Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+
+ 1 11 52 ...widths
+ ------------------------------------------------------
+ x: |s| e | f |
+ ------------------------------------------------------
+ msb lsb msb lsb ...order
+
+
+ ------------------------ ------------------------
+ x0: |s| e | f1 | x1: | f2 |
+ ------------------------ ------------------------
+
+ By performing shifts and subtracts on x0 and x1 (both regarded
+ as integers), we obtain an 8-bit approximation of sqrt(x) as
+ follows.
+
+ k := (x0>>1) + 0x1ff80000;
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+ Here k is a 32-bit integer and T1[] is an integer array containing
+ correction terms. Now magically the floating value of y (y's
+ leading 32-bit word is y0, the value of its trailing word is 0)
+ approximates sqrt(x) to almost 8-bit.
+
+ Value of T1:
+ static int T1[32]= {
+ 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
+ 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
+ 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
+
+ (2) Iterative refinement
+
+ Apply Heron's rule three times to y, we have y approximates
+ sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+ y := (y+x/y)/2 ... almost 17 sig. bits
+ y := (y+x/y)/2 ... almost 35 sig. bits
+ y := y-(y-x/y)/2 ... within 1 ulp
+
+
+ Remark 1.
+ Another way to improve y to within 1 ulp is:
+
+ y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
+ y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
+
+ 2
+ (x-y )*y
+ y := y + 2* ---------- ...within 1 ulp
+ 2
+ 3y + x
+
+
+ This formula has one division fewer than the one above; however,
+ it requires more multiplications and additions. Also x must be
+ scaled in advance to avoid spurious overflow in evaluating the
+ expression 3y*y+x. Hence it is not recommended uless division
+ is slow. If division is very slow, then one should use the
+ reciproot algorithm given in section B.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ I := FALSE; ... reset INEXACT flag I
+ R := RZ; ... set rounding mode to round-toward-zero
+ z := x/y; ... chopped quotient, possibly inexact
+ If(not I) then { ... if the quotient is exact
+ if(z=y) {
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+ } else {
+ z := z - ulp; ... special rounding
+ }
+ }
+ i := TRUE; ... sqrt(x) is inexact
+ If (r=RN) then z=z+ulp ... rounded-to-nearest
+ If (r=RP) then { ... round-toward-+inf
+ y = y+ulp; z=z+ulp;
+ }
+ y := y+z; ... chopped sum
+ y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+
+ (4) Special cases
+
+ Square root of +inf, +-0, or NaN is itself;
+ Square root of a negative number is NaN with invalid signal.
+
+
+B. sqrt(x) by Reciproot Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+ (see section A). By performing shifs and subtracts on x0 and y0,
+ we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+ k := 0x5fe80000 - (x0>>1);
+ y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
+
+ Here k is a 32-bit integer and T2[] is an integer array
+ containing correction terms. Now magically the floating
+ value of y (y's leading 32-bit word is y0, the value of
+ its trailing word y1 is set to zero) approximates 1/sqrt(x)
+ to almost 7.8-bit.
+
+ Value of T2:
+ static int T2[64]= {
+ 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+ (2) Iterative refinement
+
+ Apply Reciproot iteration three times to y and multiply the
+ result by x to get an approximation z that matches sqrt(x)
+ to about 1 ulp. To be exact, we will have
+ -1ulp < sqrt(x)-z<1.0625ulp.
+
+ ... set rounding mode to Round-to-nearest
+ y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
+ y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+ ... special arrangement for better accuracy
+ z := x*y ... 29 bits to sqrt(x), with z*y<1
+ z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
+
+ Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+ (a) the term z*y in the final iteration is always less than 1;
+ (b) the error in the final result is biased upward so that
+ -1 ulp < sqrt(x) - z < 1.0625 ulp
+ instead of |sqrt(x)-z|<1.03125ulp.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ R := RZ; ... set rounding mode to round-toward-zero
+ switch(r) {
+ case RN: ... round-to-nearest
+ if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+ if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+ break;
+ case RZ:case RM: ... round-to-zero or round-to--inf
+ R:=RP; ... reset rounding mod to round-to-+inf
+ if(x<z*z ... rounded up) z = z - ulp; else
+ if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+ break;
+ case RP: ... round-to-+inf
+ if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+ if(x>z*z ...chopped) z = z+ulp;
+ break;
+ }
+
+ Remark 3. The above comparisons can be done in fixed point. For
+ example, to compare x and w=z*z chopped, it suffices to compare
+ x1 and w1 (the trailing parts of x and w), regarding them as
+ two's complement integers.
+
+ ...Is z an exact square root?
+ To determine whether z is an exact square root of x, let z1 be the
+ trailing part of z, and also let x0 and x1 be the leading and
+ trailing parts of x.
+
+ If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+ I := 1; ... Raise Inexact flag: z is not exact
+ else {
+ j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
+ k := z1 >> 26; ... get z's 25-th and 26-th
+ fraction bits
+ I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+ }
+ R:= r ... restore rounded mode
+ return sqrt(x):=z.
+
+ If multiplication is cheaper then the foregoing red tape, the
+ Inexact flag can be evaluated by
+
+ I := i;
+ I := (z*z!=x) or I.
+
+ Note that z*z can overwrite I; this value must be sensed if it is
+ True.
+
+ Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+ zero.
+
+ --------------------
+ z1: | f2 |
+ --------------------
+ bit 31 bit 0
+
+ Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+ or even of logb(x) have the following relations:
+
+ -------------------------------------------------
+ bit 27,26 of z1 bit 1,0 of x1 logb(x)
+ -------------------------------------------------
+ 00 00 odd and even
+ 01 01 even
+ 10 10 odd
+ 10 00 even
+ 11 01 even
+ -------------------------------------------------
+
+ (4) Special cases (see (4) of Section A).
+
+ */
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/3dfx_mmio.h b/distrib/sdl-1.2.15/src/video/fbcon/3dfx_mmio.h
new file mode 100644
index 0000000..b641454
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/3dfx_mmio.h
@@ -0,0 +1,56 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* 3Dfx register definitions */
+
+#include "3dfx_regs.h"
+
+/* 3Dfx control macros */
+
+#define tdfx_in8(reg) *(volatile Uint8 *)(mapped_io + (reg))
+#define tdfx_in32(reg) *(volatile Uint32 *)(mapped_io + (reg))
+
+#define tdfx_out8(reg,v) *(volatile Uint8 *)(mapped_io + (reg)) = v;
+#define tdfx_out32(reg,v) *(volatile Uint32 *)(mapped_io + (reg)) = v;
+
+
+/* Wait for fifo space */
+#define tdfx_wait(space) \
+{ \
+ while ( (tdfx_in8(TDFX_STATUS) & 0x1F) < space ) \
+ ; \
+}
+
+
+/* Wait for idle accelerator */
+#define tdfx_waitidle() \
+{ \
+ int i = 0; \
+ \
+ tdfx_wait(1); \
+ tdfx_out32(COMMAND_3D, COMMAND_3D_NOP); \
+ do { \
+ i = (tdfx_in32(TDFX_STATUS) & STATUS_BUSY) ? 0 : i + 1; \
+ } while ( i != 3 ); \
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/3dfx_regs.h b/distrib/sdl-1.2.15/src/video/fbcon/3dfx_regs.h
new file mode 100644
index 0000000..e86f727
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/3dfx_regs.h
@@ -0,0 +1,83 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 _3DFX_REGS_H
+#define _3DFX_REGS_H
+
+/* This information comes from the public 3Dfx specs for the Voodoo 3000 */
+
+/* mapped_io register offsets */
+#define TDFX_STATUS 0x00
+
+#define INTCTRL (0x00100000 + 0x04)
+#define CLIP0MIN (0x00100000 + 0x08)
+#define CLIP0MAX (0x00100000 + 0x0c)
+#define DSTBASE (0x00100000 + 0x10)
+#define DSTFORMAT (0x00100000 + 0x14)
+#define SRCCOLORKEYMIN (0x00100000 + 0x18)
+#define SRCCOLORKEYMAX (0x00100000 + 0x1c)
+#define DSTCOLORKEYMIN (0x00100000 + 0x20)
+#define DSTCOLORKEYMAX (0x00100000 + 0x24)
+#define BRESERROR0 (0x00100000 + 0x28)
+#define BRESERROR1 (0x00100000 + 0x2c)
+#define ROP_2D (0x00100000 + 0x30)
+#define SRCBASE (0x00100000 + 0x34)
+#define COMMANDEXTRA_2D (0x00100000 + 0x38)
+#define PATTERN0 (0x00100000 + 0x44)
+#define PATTERN1 (0x00100000 + 0x48)
+#define CLIP1MIN (0x00100000 + 0x4c)
+#define CLIP1MAX (0x00100000 + 0x50)
+#define SRCFORMAT (0x00100000 + 0x54)
+#define SRCSIZE (0x00100000 + 0x58)
+#define SRCXY (0x00100000 + 0x5c)
+#define COLORBACK (0x00100000 + 0x60)
+#define COLORFORE (0x00100000 + 0x64)
+#define DSTSIZE (0x00100000 + 0x68)
+#define DSTXY (0x00100000 + 0x6c)
+#define COMMAND_2D (0x00100000 + 0x70)
+#define LAUNCH_2D (0x00100000 + 0x80)
+#define PATTERNBASE (0x00100000 + 0x100)
+
+#define COMMAND_3D (0x00200000 + 0x120)
+
+/* register bitfields (not all, only as needed) */
+
+#define BIT(x) (1UL << (x))
+
+#define COMMAND_2D_BITBLT 0x01
+#define COMMAND_2D_FILLRECT 0x05
+#define COMMAND_2D_LINE 0x06
+#define COMMAND_2D_POLYGON_FILL 0x08
+#define COMMAND_2D_INITIATE BIT(8)
+#define COMMAND_2D_REVERSELINE BIT(9)
+#define COMMAND_2D_STIPPLELINE BIT(12)
+#define COMMAND_2D_MONOCHROME_PATT BIT(13)
+#define COMMAND_2D_MONOCHROME_TRANSP BIT(16)
+
+#define COMMAND_3D_NOP 0x00
+
+#define STATUS_RETRACE BIT(6)
+#define STATUS_BUSY BIT(9)
+
+#endif /* _3DFX_REGS_H */
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.c
new file mode 100644
index 0000000..eb083b8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.c
@@ -0,0 +1,215 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "../SDL_blit.h"
+#include "SDL_fb3dfx.h"
+#include "3dfx_mmio.h"
+
+
+/* Wait for vertical retrace */
+static void WaitVBL(_THIS)
+{
+ /* find start of retrace */
+ tdfx_waitidle();
+ while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == STATUS_RETRACE )
+ ;
+ /* wait until we're past the start */
+ while( (tdfx_in32(TDFX_STATUS) & STATUS_RETRACE) == 0 )
+ ;
+}
+static void WaitIdle(_THIS)
+{
+ tdfx_waitidle();
+}
+
+/* Sets video mem colorkey and accelerated blit function */
+static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ return(0);
+}
+
+static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
+{
+ int bpp;
+ Uint32 dst_base;
+ Uint32 format;
+ int dstX, dstY;
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ /* Set the destination pixel format */
+ dst_base = ((char *)dst->pixels - mapped_mem);
+ bpp = dst->format->BitsPerPixel;
+ format = dst->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13);
+
+ /* Calculate source and destination base coordinates */
+ dstX = rect->x;
+ dstY = rect->y;
+
+ /* Execute the fill command */
+ tdfx_wait(6);
+ tdfx_out32(DSTBASE, dst_base);
+ tdfx_out32(DSTFORMAT, format);
+ tdfx_out32(COLORFORE, color);
+ tdfx_out32(COMMAND_2D, COMMAND_2D_FILLRECT);
+ tdfx_out32(DSTSIZE, rect->w | (rect->h << 16));
+ tdfx_out32(LAUNCH_2D, dstX | (dstY << 16));
+
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_VideoDevice *this = current_video;
+ int bpp;
+ Uint32 src_format;
+ Uint32 src_base;
+ Uint32 dst_base;
+ int srcX, srcY;
+ int dstX, dstY;
+ Uint32 blitop;
+ Uint32 use_colorkey;
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ /* Set the source and destination pixel format */
+ src_base = ((char *)src->pixels - mapped_mem);
+ bpp = src->format->BitsPerPixel;
+ src_format = src->pitch | ((bpp+((bpp==8) ? 0 : 8)) << 13);
+ dst_base = ((char *)dst->pixels - mapped_mem);
+ bpp = dst->format->BitsPerPixel;
+
+ srcX = srcrect->x;
+ srcY = srcrect->y;
+ dstX = dstrect->x;
+ dstY = dstrect->y;
+
+ /* Assemble the blit operation */
+ blitop = COMMAND_2D_BITBLT | (0xCC << 24);
+ if ( srcX <= dstX ) {
+ blitop |= BIT(14);
+ srcX += (dstrect->w - 1);
+ dstX += (dstrect->w - 1);
+ }
+ if ( srcY <= dstY ) {
+ blitop |= BIT(15);
+ srcY += (dstrect->h - 1);
+ dstY += (dstrect->h - 1);
+ }
+
+ /* Perform the blit! */
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ tdfx_wait(3);
+ tdfx_out32(SRCCOLORKEYMIN, src->format->colorkey);
+ tdfx_out32(SRCCOLORKEYMAX, src->format->colorkey);
+ tdfx_out32(ROP_2D, 0xAA00);
+ use_colorkey = 1;
+ } else {
+ use_colorkey = 0;
+ }
+ tdfx_wait(9);
+ tdfx_out32(SRCBASE, (Uint32)src_base);
+ tdfx_out32(SRCFORMAT, src_format);
+ tdfx_out32(DSTBASE, (Uint32)dst_base);
+ tdfx_out32(DSTFORMAT, src_format);
+ tdfx_out32(COMMAND_2D, blitop);
+ tdfx_out32(COMMANDEXTRA_2D, use_colorkey);
+ tdfx_out32(DSTSIZE, dstrect->w | (dstrect->h << 16));
+ tdfx_out32(DSTXY, dstX | (dstY << 16));
+ tdfx_out32(LAUNCH_2D, srcX | (srcY << 16));
+
+ FB_AddBusySurface(src);
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ int accelerated;
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! this->info.blit_hw_A ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! this->info.blit_hw_CC ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+ src->map->hw_blit = HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+void FB_3DfxAccel(_THIS, __u32 card)
+{
+ /* We have hardware accelerated surface functions */
+ this->CheckHWBlit = CheckHWBlit;
+ wait_vbl = WaitVBL;
+ wait_idle = WaitIdle;
+
+ /* Reset the 3Dfx controller */
+ tdfx_out32(BRESERROR0, 0);
+ tdfx_out32(BRESERROR1, 0);
+
+ /* The 3Dfx has an accelerated color fill */
+ this->info.blit_fill = 1;
+ this->FillHWRect = FillHWRect;
+
+ /* The 3Dfx has accelerated normal and colorkey blits */
+ this->info.blit_hw = 1;
+ this->info.blit_hw_CC = 1;
+ this->SetHWColorKey = SetHWColorKey;
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.h
new file mode 100644
index 0000000..4a59de9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fb3dfx.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* 3Dfx hardware acceleration for the SDL framebuffer console driver */
+
+#include "SDL_fbvideo.h"
+
+/* Set up the driver for 3Dfx acceleration */
+extern void FB_3DfxAccel(_THIS, __u32 card);
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.c
new file mode 100644
index 0000000..63dff87
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.c
@@ -0,0 +1,442 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <unistd.h>
+#include <sys/time.h>
+#include <ctype.h>
+
+#include "SDL_stdinc.h"
+#include "SDL_fbvideo.h"
+#include "SDL_fbelo.h"
+
+/*
+ calibration default values
+ values are read from the following environment variables:
+
+ SDL_ELO_MIN_X
+ SDL_ELO_MAX_X
+ SDL_ELO_MIN_Y
+ SDL_ELO_MAX_Y
+*/
+
+static int ELO_MIN_X = 400;
+static int ELO_MAX_X = 3670;
+static int ELO_MIN_Y = 500;
+static int ELO_MAX_Y = 3540;
+
+#define ELO_SNAP_SIZE 6
+#define ELO_TOUCH_BYTE 'T'
+#define ELO_ID 'I'
+#define ELO_MODE 'M'
+#define ELO_PARAMETER 'P'
+#define ELO_REPORT 'B'
+#define ELO_ACK 'A'
+
+#define ELO_INIT_CHECKSUM 0xAA
+
+#define ELO_BTN_PRESS 0x01
+#define ELO_STREAM 0x02
+#define ELO_BTN_RELEASE 0x04
+
+#define ELO_TOUCH_MODE 0x01
+#define ELO_STREAM_MODE 0x02
+#define ELO_UNTOUCH_MODE 0x04
+#define ELO_RANGE_CHECK_MODE 0x40
+#define ELO_TRIM_MODE 0x02
+#define ELO_CALIB_MODE 0x04
+#define ELO_SCALING_MODE 0x08
+#define ELO_TRACKING_MODE 0x40
+
+#define ELO_SERIAL_MASK 0xF8
+
+#define ELO_SERIAL_IO '0'
+
+#define ELO_MAX_TRIALS 3
+#define ELO_MAX_WAIT 100000
+#define ELO_UNTOUCH_DELAY 5
+#define ELO_REPORT_DELAY 1
+
+/* eloParsePacket
+*/
+int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state) {
+ static int elo_button = 0;
+ static int last_x = 0;
+ static int last_y = 0;
+ int x,y;
+
+ /* Check if we have a touch packet */
+ if (mousebuf[1] != ELO_TOUCH_BYTE) {
+ return 0;
+ }
+
+ x = ((mousebuf[4] << 8) | mousebuf[3]);
+ y = ((mousebuf[6] << 8) | mousebuf[5]);
+
+ if((SDL_abs(x - last_x) > ELO_SNAP_SIZE) || (SDL_abs(y - last_y) > ELO_SNAP_SIZE)) {
+ *dx = ((mousebuf[4] << 8) | mousebuf[3]);
+ *dy = ((mousebuf[6] << 8) | mousebuf[5]);
+ }
+ else {
+ *dx = last_x;
+ *dy = last_y;
+ }
+
+ last_x = *dx;
+ last_y = *dy;
+
+ if ( (mousebuf[2] & 0x07) == ELO_BTN_PRESS ) {
+ elo_button = 1;
+ }
+ if ( (mousebuf[2] & 0x07) == ELO_BTN_RELEASE ) {
+ elo_button = 0;
+ }
+
+ *button_state = elo_button;
+ return 1;
+}
+
+/* Convert the raw coordinates from the ELO controller
+ to a screen position.
+*/
+void eloConvertXY(_THIS, int *dx, int *dy) {
+ int input_x = *dx;
+ int input_y = *dy;
+ int width = ELO_MAX_X - ELO_MIN_X;
+ int height = ELO_MAX_Y - ELO_MIN_Y;
+
+ *dx = ((int)cache_vinfo.xres - ((int)cache_vinfo.xres * (input_x - ELO_MIN_X)) / width);
+ *dy = (cache_vinfo.yres * (input_y - ELO_MIN_Y)) / height;
+}
+
+
+/* eloGetPacket
+*/
+int eloGetPacket(unsigned char* buffer, int* buffer_p, int* checksum, int fd) {
+ int num_bytes;
+ int ok;
+
+ if(fd == 0) {
+ num_bytes = ELO_PACKET_SIZE;
+ }
+ else {
+ num_bytes = read(fd,
+ (char *) (buffer + *buffer_p),
+ ELO_PACKET_SIZE - *buffer_p);
+ }
+
+ if (num_bytes < 0) {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "System error while reading from Elographics touchscreen.\n");
+#endif
+ return 0;
+ }
+
+ while (num_bytes) {
+ if ((*buffer_p == 0) && (buffer[0] != ELO_START_BYTE)) {
+ SDL_memcpy(&buffer[0], &buffer[1], num_bytes-1);
+ }
+ else {
+ if (*buffer_p < ELO_PACKET_SIZE-1) {
+ *checksum = *checksum + buffer[*buffer_p];
+ *checksum = *checksum % 256;
+ }
+ (*buffer_p)++;
+ }
+ num_bytes--;
+ }
+
+ if (*buffer_p == ELO_PACKET_SIZE) {
+ ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
+ *checksum = ELO_INIT_CHECKSUM;
+ *buffer_p = 0;
+
+ if (!ok) {
+ return 0;
+ }
+
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* eloSendPacket
+*/
+
+int eloSendPacket(unsigned char* packet, int fd)
+{
+ int i, result;
+ int sum = ELO_INIT_CHECKSUM;
+
+ packet[0] = ELO_START_BYTE;
+ for (i = 0; i < ELO_PACKET_SIZE-1; i++) {
+ sum += packet[i];
+ sum &= 0xFF;
+ }
+ packet[ELO_PACKET_SIZE-1] = sum;
+
+ result = write(fd, packet, ELO_PACKET_SIZE);
+
+ if (result != ELO_PACKET_SIZE) {
+#ifdef DEBUG_MOUSE
+ printf("System error while sending to Elographics touchscreen.\n");
+#endif
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+
+/* eloWaitForInput
+ */
+int eloWaitForInput(int fd, int timeout)
+{
+ fd_set readfds;
+ struct timeval to;
+ int r;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ to.tv_sec = 0;
+ to.tv_usec = timeout;
+
+ r = select(FD_SETSIZE, &readfds, NULL, NULL, &to);
+ return r;
+}
+
+/* eloWaitReply
+ */
+int eloWaitReply(unsigned char type, unsigned char *reply, int fd) {
+ int ok;
+ int i, result;
+ int reply_p = 0;
+ int sum = ELO_INIT_CHECKSUM;
+
+ i = ELO_MAX_TRIALS;
+ do {
+ ok = 0;
+
+ result = eloWaitForInput(fd, ELO_MAX_WAIT);
+
+ if (result > 0) {
+ ok = eloGetPacket(reply, &reply_p, &sum, fd);
+
+ if (ok && reply[1] != type && type != ELO_PARAMETER) {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Wrong reply received\n");
+#endif
+ ok = 0;
+ }
+ }
+ else {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "No input!\n");
+#endif
+ }
+
+ if (result == 0) {
+ i--;
+ }
+ } while(!ok && (i>0));
+
+ return ok;
+}
+
+
+/* eloWaitAck
+ */
+
+int eloWaitAck(int fd) {
+ unsigned char packet[ELO_PACKET_SIZE];
+ int i, nb_errors;
+
+ if (eloWaitReply(ELO_ACK, packet, fd)) {
+ for (i = 0, nb_errors = 0; i < 4; i++) {
+ if (packet[2 + i] != '0') {
+ nb_errors++;
+ }
+ }
+
+ if (nb_errors != 0) {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Elographics acknowledge packet reports %d errors\n", nb_errors);
+#endif
+ }
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/* eloSendQuery --
+*/
+int eloSendQuery(unsigned char *request, unsigned char* reply, int fd) {
+ int ok;
+
+ if (eloSendPacket(request, fd)) {
+ ok = eloWaitReply(toupper(request[1]), reply, fd);
+ if (ok) {
+ ok = eloWaitAck(fd);
+ }
+ return ok;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/* eloSendControl
+*/
+int eloSendControl(unsigned char* control, int fd) {
+ if (eloSendPacket(control, fd)) {
+ return eloWaitAck(fd);
+ }
+ else {
+ return 0;
+ }
+}
+
+/* eloInitController
+*/
+int eloInitController(int fd) {
+ unsigned char req[ELO_PACKET_SIZE];
+ unsigned char reply[ELO_PACKET_SIZE];
+ const char *buffer = NULL;
+ int result = 0;
+
+ struct termios mouse_termios;
+
+ /* try to read the calibration values */
+ buffer = SDL_getenv("SDL_ELO_MIN_X");
+ if(buffer) {
+ ELO_MIN_X = SDL_atoi(buffer);
+ }
+ buffer = SDL_getenv("SDL_ELO_MAX_X");
+ if(buffer) {
+ ELO_MAX_X = SDL_atoi(buffer);
+ }
+ buffer = SDL_getenv("SDL_ELO_MIN_Y");
+ if(buffer) {
+ ELO_MIN_Y = SDL_atoi(buffer);
+ }
+ buffer = SDL_getenv("SDL_ELO_MAX_Y");
+ if(buffer) {
+ ELO_MAX_Y = SDL_atoi(buffer);
+ }
+
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "ELO calibration values:\nmin_x: %i\nmax_x: %i\nmin_y: %i\nmax_y: %i\n",
+ ELO_MIN_X,
+ ELO_MAX_X,
+ ELO_MIN_Y,
+ ELO_MAX_Y);
+#endif
+
+ /* set comm params */
+ SDL_memset(&mouse_termios, 0, sizeof(mouse_termios));
+ mouse_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
+ mouse_termios.c_cc[VMIN] = 1;
+ result = tcsetattr(fd, TCSANOW, &mouse_termios);
+
+ if (result < 0) {
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "Unable to configure Elographics touchscreen port\n");
+#endif
+ return 0;
+ }
+
+ SDL_memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = tolower(ELO_PARAMETER);
+ if (!eloSendQuery(req, reply, fd)) {
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "Not at the specified rate or model 2310, will continue\n");
+#endif
+ }
+
+ SDL_memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = tolower(ELO_ID);
+ if (eloSendQuery(req, reply, fd)) {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Ok, controller configured!\n");
+#endif
+ }
+ else {
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "Unable to ask Elographics touchscreen identification\n");
+#endif
+ return 0;
+ }
+
+ SDL_memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_MODE;
+ req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE;
+ req[4] = ELO_TRACKING_MODE;
+ if (!eloSendControl(req, fd)) {
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "Unable to change Elographics touchscreen operating mode\n");
+#endif
+ return 0;
+ }
+
+ SDL_memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_REPORT;
+ req[2] = ELO_UNTOUCH_DELAY;
+ req[3] = ELO_REPORT_DELAY;
+ if (!eloSendControl(req, fd)) {
+#ifdef DEBUG_MOUSE
+ fprintf( stderr, "Unable to change Elographics touchscreen reports timings\n");
+#endif
+ return 0;
+ }
+
+ return 1;
+}
+
+int eloReadPosition(_THIS, int fd, int* x, int* y, int* button_state, int* realx, int* realy) {
+ unsigned char buffer[ELO_PACKET_SIZE];
+ int pointer = 0;
+ int checksum = ELO_INIT_CHECKSUM;
+
+ while(pointer < ELO_PACKET_SIZE) {
+ if(eloGetPacket(buffer, &pointer, &checksum, fd)) {
+ break;
+ }
+ }
+
+ if(!eloParsePacket(buffer, realx, realy, button_state)) {
+ return 0;
+ }
+
+ *x = *realx;
+ *y = *realy;
+
+ eloConvertXY(this, x, y);
+
+ return 1;
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.h
new file mode 100644
index 0000000..e7fde4f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbelo.h
@@ -0,0 +1,55 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_fbelo_h
+#define SDL_fbelo_h
+
+#include "SDL_fbvideo.h"
+
+/* ELO */
+#define ELO_PACKET_SIZE 10
+#define ELO_START_BYTE 'U'
+
+/* eloConvertXY
+ Convert the raw coordinates from the ELO controller
+ to a screen position.
+*/
+void eloConvertXY(_THIS, int *dx, int *dy);
+
+/* eloInitController(int fd)
+ Initialize the ELO serial touchscreen controller
+*/
+int eloInitController(int fd);
+
+/* eloParsePacket
+ extract position and button state from a packet
+*/
+int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state);
+
+/* eloReadPosition
+ read a packet and get the cursor position
+*/
+
+int eloReadPosition(_THIS, int fd, int* x, int* y, int* button_state, int* realx, int* realy);
+
+#endif /* SDL_fbelo_h */
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents.c
new file mode 100644
index 0000000..5e369a4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents.c
@@ -0,0 +1,1254 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting console events into SDL events */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+/* For parsing /proc */
+#include <dirent.h>
+#include <ctype.h>
+
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+
+#include "SDL_timer.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_fbvideo.h"
+#include "SDL_fbevents_c.h"
+#include "SDL_fbkeys.h"
+
+#include "SDL_fbelo.h"
+
+#ifndef GPM_NODE_FIFO
+#define GPM_NODE_FIFO "/dev/gpmdata"
+#endif
+
+/*#define DEBUG_KEYBOARD*/
+/*#define DEBUG_MOUSE*/
+
+/* The translation tables from a console scancode to a SDL keysym */
+#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
+static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS];
+static SDLKey keymap[128];
+static Uint16 keymap_temp[128]; /* only used at startup */
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
+
+/* Ugh, we have to duplicate the kernel's keysym mapping code...
+ Oh, it's not so bad. :-)
+
+ FIXME: Add keyboard LED handling code
+ */
+static void FB_vgainitkeymaps(int fd)
+{
+ struct kbentry entry;
+ int map, i;
+
+ /* Don't do anything if we are passed a closed keyboard */
+ if ( fd < 0 ) {
+ return;
+ }
+
+ /* Load all the keysym mappings */
+ for ( map=0; map<NUM_VGAKEYMAPS; ++map ) {
+ SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16));
+ for ( i=0; i<NR_KEYS; ++i ) {
+ entry.kb_table = map;
+ entry.kb_index = i;
+ if ( ioctl(fd, KDGKBENT, &entry) == 0 ) {
+ /* fill keytemp. This replaces SDL_fbkeys.h */
+ if ( (map == 0) && (i<128) ) {
+ keymap_temp[i] = entry.kb_value;
+ }
+ /* The "Enter" key is a special case */
+ if ( entry.kb_value == K_ENTER ) {
+ entry.kb_value = K(KT_ASCII,13);
+ }
+ /* Handle numpad specially as well */
+ if ( KTYP(entry.kb_value) == KT_PAD ) {
+ switch ( entry.kb_value ) {
+ case K_P0:
+ case K_P1:
+ case K_P2:
+ case K_P3:
+ case K_P4:
+ case K_P5:
+ case K_P6:
+ case K_P7:
+ case K_P8:
+ case K_P9:
+ vga_keymap[map][i]=entry.kb_value;
+ vga_keymap[map][i]+= '0';
+ break;
+ case K_PPLUS:
+ vga_keymap[map][i]=K(KT_ASCII,'+');
+ break;
+ case K_PMINUS:
+ vga_keymap[map][i]=K(KT_ASCII,'-');
+ break;
+ case K_PSTAR:
+ vga_keymap[map][i]=K(KT_ASCII,'*');
+ break;
+ case K_PSLASH:
+ vga_keymap[map][i]=K(KT_ASCII,'/');
+ break;
+ case K_PENTER:
+ vga_keymap[map][i]=K(KT_ASCII,'\r');
+ break;
+ case K_PCOMMA:
+ vga_keymap[map][i]=K(KT_ASCII,',');
+ break;
+ case K_PDOT:
+ vga_keymap[map][i]=K(KT_ASCII,'.');
+ break;
+ default:
+ break;
+ }
+ }
+ /* Do the normal key translation */
+ if ( (KTYP(entry.kb_value) == KT_LATIN) ||
+ (KTYP(entry.kb_value) == KT_ASCII) ||
+ (KTYP(entry.kb_value) == KT_LETTER) ) {
+ vga_keymap[map][i] = entry.kb_value;
+ }
+ }
+ }
+ }
+}
+
+int FB_InGraphicsMode(_THIS)
+{
+ return((keyboard_fd >= 0) && (saved_kbd_mode >= 0));
+}
+
+int FB_EnterGraphicsMode(_THIS)
+{
+ struct termios keyboard_termios;
+
+ /* Set medium-raw keyboard mode */
+ if ( (keyboard_fd >= 0) && !FB_InGraphicsMode(this) ) {
+
+ /* Switch to the correct virtual terminal */
+ if ( current_vt > 0 ) {
+ struct vt_stat vtstate;
+
+ if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) {
+ saved_vt = vtstate.v_active;
+ }
+ if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) {
+ ioctl(keyboard_fd, VT_WAITACTIVE, current_vt);
+ }
+ }
+
+ /* Set the terminal input mode */
+ if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) {
+ SDL_SetError("Unable to get terminal attributes");
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ keyboard_fd = -1;
+ return(-1);
+ }
+ if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) {
+ SDL_SetError("Unable to get current keyboard mode");
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ keyboard_fd = -1;
+ return(-1);
+ }
+ keyboard_termios = saved_kbd_termios;
+ keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
+ keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
+ keyboard_termios.c_cc[VMIN] = 0;
+ keyboard_termios.c_cc[VTIME] = 0;
+ if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) {
+ FB_CloseKeyboard(this);
+ SDL_SetError("Unable to set terminal attributes");
+ return(-1);
+ }
+ /* This will fail if we aren't root or this isn't our tty */
+ if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) {
+ FB_CloseKeyboard(this);
+ SDL_SetError("Unable to set keyboard in raw mode");
+ return(-1);
+ }
+ if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) {
+ FB_CloseKeyboard(this);
+ SDL_SetError("Unable to set keyboard in graphics mode");
+ return(-1);
+ }
+ /* Prevent switching the virtual terminal */
+ ioctl(keyboard_fd, VT_LOCKSWITCH, 1);
+ }
+ return(keyboard_fd);
+}
+
+void FB_LeaveGraphicsMode(_THIS)
+{
+ if ( FB_InGraphicsMode(this) ) {
+ ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
+ ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode);
+ tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios);
+ saved_kbd_mode = -1;
+
+ /* Head back over to the original virtual terminal */
+ ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1);
+ if ( saved_vt > 0 ) {
+ ioctl(keyboard_fd, VT_ACTIVATE, saved_vt);
+ }
+ }
+}
+
+void FB_CloseKeyboard(_THIS)
+{
+ if ( keyboard_fd >= 0 ) {
+ FB_LeaveGraphicsMode(this);
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ }
+ keyboard_fd = -1;
+}
+
+int FB_OpenKeyboard(_THIS)
+{
+ /* Open only if not already opened */
+ if ( keyboard_fd < 0 ) {
+ static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+ static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
+ int i, tty0_fd;
+
+ /* Try to query for a free virtual terminal */
+ tty0_fd = -1;
+ for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) {
+ tty0_fd = open(tty0[i], O_WRONLY, 0);
+ }
+ if ( tty0_fd < 0 ) {
+ tty0_fd = dup(0); /* Maybe stdin is a VT? */
+ }
+ ioctl(tty0_fd, VT_OPENQRY, &current_vt);
+ close(tty0_fd);
+ if ( (geteuid() == 0) && (current_vt > 0) ) {
+ for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) {
+ char vtpath[12];
+
+ SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt);
+ keyboard_fd = open(vtpath, O_RDWR, 0);
+#ifdef DEBUG_KEYBOARD
+ fprintf(stderr, "vtpath = %s, fd = %d\n",
+ vtpath, keyboard_fd);
+#endif /* DEBUG_KEYBOARD */
+
+ /* This needs to be our controlling tty
+ so that the kernel ioctl() calls work
+ */
+ if ( keyboard_fd >= 0 ) {
+ tty0_fd = open("/dev/tty", O_RDWR, 0);
+ if ( tty0_fd >= 0 ) {
+ ioctl(tty0_fd, TIOCNOTTY, 0);
+ close(tty0_fd);
+ }
+ }
+ }
+ }
+ if ( keyboard_fd < 0 ) {
+ /* Last resort, maybe our tty is a usable VT */
+ struct vt_stat vtstate;
+
+ keyboard_fd = open("/dev/tty", O_RDWR);
+
+ if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) {
+ current_vt = vtstate.v_active;
+ } else {
+ current_vt = 0;
+ }
+ }
+#ifdef DEBUG_KEYBOARD
+ fprintf(stderr, "Current VT: %d\n", current_vt);
+#endif
+ saved_kbd_mode = -1;
+
+ /* Make sure that our input is a console terminal */
+ { int dummy;
+ if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) {
+ close(keyboard_fd);
+ keyboard_fd = -1;
+ SDL_SetError("Unable to open a console terminal");
+ }
+ }
+
+ /* Set up keymap */
+ FB_vgainitkeymaps(keyboard_fd);
+ }
+ return(keyboard_fd);
+}
+
+static enum {
+ MOUSE_NONE = -1,
+ MOUSE_MSC, /* Note: GPM uses the MSC protocol */
+ MOUSE_PS2,
+ MOUSE_IMPS2,
+ MOUSE_MS,
+ MOUSE_BM,
+ MOUSE_ELO,
+ MOUSE_TSLIB,
+ NUM_MOUSE_DRVS
+} mouse_drv = MOUSE_NONE;
+
+void FB_CloseMouse(_THIS)
+{
+#if SDL_INPUT_TSLIB
+ if (ts_dev != NULL) {
+ ts_close(ts_dev);
+ ts_dev = NULL;
+ mouse_fd = -1;
+ }
+#endif /* SDL_INPUT_TSLIB */
+ if ( mouse_fd > 0 ) {
+ close(mouse_fd);
+ }
+ mouse_fd = -1;
+}
+
+/* Returns processes listed in /proc with the desired name */
+static int find_pid(DIR *proc, const char *wanted_name)
+{
+ struct dirent *entry;
+ int pid;
+
+ /* First scan proc for the gpm process */
+ pid = 0;
+ while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) {
+ if ( isdigit(entry->d_name[0]) ) {
+ FILE *status;
+ char path[PATH_MAX];
+ char name[PATH_MAX];
+
+ SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name);
+ status=fopen(path, "r");
+ if ( status ) {
+ int matches = 0;
+ name[0] = '\0';
+ matches = fscanf(status, "Name: %s", name);
+ if ( (matches == 1) && (SDL_strcmp(name, wanted_name) == 0) ) {
+ pid = SDL_atoi(entry->d_name);
+ }
+ fclose(status);
+ }
+ }
+ }
+ return pid;
+}
+
+/* Returns true if /dev/gpmdata is being written to by gpm */
+static int gpm_available(char *proto, size_t protolen)
+{
+ int available;
+ DIR *proc;
+ int pid;
+ int cmdline, len, arglen;
+ char path[PATH_MAX];
+ char args[PATH_MAX], *arg;
+
+ /* Don't bother looking if the fifo isn't there */
+#ifdef DEBUG_MOUSE
+ fprintf(stderr,"testing gpm\n");
+#endif
+ if ( access(GPM_NODE_FIFO, F_OK) < 0 ) {
+ return(0);
+ }
+
+ available = 0;
+ proc = opendir("/proc");
+ if ( proc ) {
+ char raw_proto[10] = { '\0' };
+ char repeat_proto[10] = { '\0' };
+ while ( !available && (pid=find_pid(proc, "gpm")) > 0 ) {
+ SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid);
+ cmdline = open(path, O_RDONLY, 0);
+ if ( cmdline >= 0 ) {
+ len = read(cmdline, args, sizeof(args));
+ arg = args;
+ while ( len > 0 ) {
+ arglen = SDL_strlen(arg)+1;
+#ifdef DEBUG_MOUSE
+ fprintf(stderr,"gpm arg %s len %d\n",arg,arglen);
+#endif
+ if ( SDL_strcmp(arg, "-t") == 0) {
+ /* protocol string, keep it for later */
+ char *t, *s;
+ t = arg + arglen;
+ s = SDL_strchr(t, ' ');
+ if (s) *s = 0;
+ SDL_strlcpy(raw_proto, t, SDL_arraysize(raw_proto));
+ if (s) *s = ' ';
+ }
+ if ( SDL_strncmp(arg, "-R", 2) == 0 ) {
+ char *t, *s;
+ available = 1;
+ t = arg + 2;
+ s = SDL_strchr(t, ' ');
+ if (s) *s = 0;
+ SDL_strlcpy(repeat_proto, t, SDL_arraysize(repeat_proto));
+ if (s) *s = ' ';
+ }
+ len -= arglen;
+ arg += arglen;
+ }
+ close(cmdline);
+ }
+ }
+ closedir(proc);
+
+ if ( available ) {
+ if ( SDL_strcmp(repeat_proto, "raw") == 0 ) {
+ SDL_strlcpy(proto, raw_proto, protolen);
+ } else if ( *repeat_proto ) {
+ SDL_strlcpy(proto, repeat_proto, protolen);
+ } else {
+ SDL_strlcpy(proto, "msc", protolen);
+ }
+ }
+ }
+ return available;
+}
+
+
+/* rcg06112001 Set up IMPS/2 mode, if possible. This gives
+ * us access to the mousewheel, etc. Returns zero if
+ * writes to device failed, but you still need to query the
+ * device to see which mode it's actually in.
+ */
+static int set_imps2_mode(int fd)
+{
+ /* If you wanted to control the mouse mode (and we do :) ) ...
+ Set IMPS/2 protocol:
+ {0xf3,200,0xf3,100,0xf3,80}
+ Reset mouse device:
+ {0xFF}
+ */
+ Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};
+ /*Uint8 reset = 0xff;*/
+ fd_set fdset;
+ struct timeval tv;
+ int retval = 0;
+
+ if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
+ /* Don't reset it, that'll clear IMPS/2 mode on some mice
+ if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
+ retval = 1;
+ }
+ */
+ }
+
+ /* Get rid of any chatter from the above */
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
+ char temp[32];
+ if (read(fd, temp, sizeof(temp)) <= 0) {
+ break;
+ }
+ }
+
+ return retval;
+}
+
+
+/* Returns true if the mouse uses the IMPS/2 protocol */
+static int detect_imps2(int fd)
+{
+ int imps2;
+
+ imps2 = 0;
+
+ if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) {
+ imps2 = 1;
+ }
+ if ( ! imps2 ) {
+ Uint8 query_ps2 = 0xF2;
+ fd_set fdset;
+ struct timeval tv;
+
+ /* Get rid of any mouse motion noise */
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
+ char temp[32];
+ if (read(fd, temp, sizeof(temp)) <= 0) {
+ break;
+ }
+ }
+
+ /* Query for the type of mouse protocol */
+ if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) {
+ Uint8 ch = 0;
+
+ /* Get the mouse protocol response */
+ do {
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) {
+ break;
+ }
+ } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) &&
+ ((ch == 0xFA) || (ch == 0xAA)) );
+
+ /* Experimental values (Logitech wheelmouse) */
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Last mouse mode: 0x%x\n", ch);
+#endif
+ if ( (ch == 3) || (ch == 4) ) {
+ imps2 = 1;
+ }
+ }
+ }
+ return imps2;
+}
+
+int FB_OpenMouse(_THIS)
+{
+ int i;
+ const char *mousedev;
+ const char *mousedrv;
+
+ mousedrv = SDL_getenv("SDL_MOUSEDRV");
+ mousedev = SDL_getenv("SDL_MOUSEDEV");
+ mouse_fd = -1;
+
+#if SDL_INPUT_TSLIB
+ if ( mousedrv && (SDL_strcmp(mousedrv, "TSLIB") == 0) ) {
+ if (mousedev == NULL) mousedev = SDL_getenv("TSLIB_TSDEVICE");
+ if (mousedev != NULL) {
+ ts_dev = ts_open(mousedev, 1);
+ if ((ts_dev != NULL) && (ts_config(ts_dev) >= 0)) {
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Using tslib touchscreen\n");
+#endif
+ mouse_drv = MOUSE_TSLIB;
+ mouse_fd = ts_fd(ts_dev);
+ return mouse_fd;
+ }
+ }
+ mouse_drv = MOUSE_NONE;
+ return mouse_fd;
+ }
+#endif /* SDL_INPUT_TSLIB */
+
+ /* ELO TOUCHSCREEN SUPPORT */
+
+ if ( mousedrv && (SDL_strcmp(mousedrv, "ELO") == 0) ) {
+ mouse_fd = open(mousedev, O_RDWR);
+ if ( mouse_fd >= 0 ) {
+ if(eloInitController(mouse_fd)) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using ELO touchscreen\n");
+#endif
+ mouse_drv = MOUSE_ELO;
+ }
+
+ }
+ else if ( mouse_fd < 0 ) {
+ mouse_drv = MOUSE_NONE;
+ }
+
+ return(mouse_fd);
+ }
+
+ /* STD MICE */
+
+ if ( mousedev == NULL ) {
+ /* FIXME someday... allow multiple mice in this driver */
+ static const char *ps2mice[] = {
+ "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL
+ };
+ /* First try to use GPM in repeater mode */
+ if ( mouse_fd < 0 ) {
+ char proto[10];
+ if ( gpm_available(proto, SDL_arraysize(proto)) ) {
+ mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+ if ( SDL_strcmp(proto, "msc") == 0 ) {
+ mouse_drv = MOUSE_MSC;
+ } else if ( SDL_strcmp(proto, "ps2") == 0 ) {
+ mouse_drv = MOUSE_PS2;
+ } else if ( SDL_strcmp(proto, "imps2") == 0 ) {
+ mouse_drv = MOUSE_IMPS2;
+ } else if ( SDL_strcmp(proto, "ms") == 0 ||
+ SDL_strcmp(proto, "bare") == 0 ) {
+ mouse_drv = MOUSE_MS;
+ } else if ( SDL_strcmp(proto, "bm") == 0 ) {
+ mouse_drv = MOUSE_BM;
+ } else {
+ /* Unknown protocol... */
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "GPM mouse using unknown protocol = %s\n", proto);
+#endif
+ close(mouse_fd);
+ mouse_fd = -1;
+ }
+ }
+#ifdef DEBUG_MOUSE
+ if ( mouse_fd >= 0 ) {
+ fprintf(stderr, "Using GPM mouse, protocol = %s\n", proto);
+ }
+#endif /* DEBUG_MOUSE */
+ }
+ }
+ /* Now try to use a modern PS/2 mouse */
+ for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) {
+ mouse_fd = open(ps2mice[i], O_RDWR, 0);
+ if (mouse_fd < 0) {
+ mouse_fd = open(ps2mice[i], O_RDONLY, 0);
+ }
+ if (mouse_fd >= 0) {
+ /* rcg06112001 Attempt to set IMPS/2 mode */
+ set_imps2_mode(mouse_fd);
+ if (detect_imps2(mouse_fd)) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using IMPS2 mouse\n");
+#endif
+ mouse_drv = MOUSE_IMPS2;
+ } else {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using PS2 mouse\n");
+#endif
+ mouse_drv = MOUSE_PS2;
+ }
+ }
+ }
+ /* Next try to use a PPC ADB port mouse */
+ if ( mouse_fd < 0 ) {
+ mouse_fd = open("/dev/adbmouse", O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using ADB mouse\n");
+#endif
+ mouse_drv = MOUSE_BM;
+ }
+ }
+ }
+ /* Default to a serial Microsoft mouse */
+ if ( mouse_fd < 0 ) {
+ if ( mousedev == NULL ) {
+ mousedev = "/dev/mouse";
+ }
+ mouse_fd = open(mousedev, O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+ struct termios mouse_termios;
+
+ /* Set the sampling speed to 1200 baud */
+ tcgetattr(mouse_fd, &mouse_termios);
+ mouse_termios.c_iflag = IGNBRK | IGNPAR;
+ mouse_termios.c_oflag = 0;
+ mouse_termios.c_lflag = 0;
+ mouse_termios.c_line = 0;
+ mouse_termios.c_cc[VTIME] = 0;
+ mouse_termios.c_cc[VMIN] = 1;
+ mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL;
+ mouse_termios.c_cflag |= CS8;
+ mouse_termios.c_cflag |= B1200;
+ tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios);
+ if ( mousedrv && (SDL_strcmp(mousedrv, "PS2") == 0) ) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using (user specified) PS2 mouse on %s\n", mousedev);
+#endif
+ mouse_drv = MOUSE_PS2;
+ } else {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using (default) MS mouse on %s\n", mousedev);
+#endif
+ mouse_drv = MOUSE_MS;
+ }
+ }
+ }
+ if ( mouse_fd < 0 ) {
+ mouse_drv = MOUSE_NONE;
+ }
+ return(mouse_fd);
+}
+
+static int posted = 0;
+
+void FB_vgamousecallback(int button, int relative, int dx, int dy)
+{
+ int button_1, button_3;
+ int button_state;
+ int state_changed;
+ int i;
+ Uint8 state;
+
+ if ( dx || dy ) {
+ posted += SDL_PrivateMouseMotion(0, relative, dx, dy);
+ }
+
+ /* Swap button 1 and 3 */
+ button_1 = (button & 0x04) >> 2;
+ button_3 = (button & 0x01) << 2;
+ button &= ~0x05;
+ button |= (button_1|button_3);
+
+ /* See what changed */
+ button_state = SDL_GetMouseState(NULL, NULL);
+ state_changed = button_state ^ button;
+ for ( i=0; i<8; ++i ) {
+ if ( state_changed & (1<<i) ) {
+ if ( button & (1<<i) ) {
+ state = SDL_PRESSED;
+ } else {
+ state = SDL_RELEASED;
+ }
+ posted += SDL_PrivateMouseButton(state, i+1, 0, 0);
+ }
+ }
+}
+
+/* Handle input from tslib */
+#if SDL_INPUT_TSLIB
+static void handle_tslib(_THIS)
+{
+ struct ts_sample sample;
+ int button;
+
+ while (ts_read(ts_dev, &sample, 1) > 0) {
+ button = (sample.pressure > 0) ? 1 : 0;
+ button <<= 2; /* must report it as button 3 */
+ FB_vgamousecallback(button, 0, sample.x, sample.y);
+ }
+ return;
+}
+#endif /* SDL_INPUT_TSLIB */
+
+/* For now, use MSC, PS/2, and MS protocols
+ Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.)
+ */
+static void handle_mouse(_THIS)
+{
+ static int start = 0;
+ static unsigned char mousebuf[BUFSIZ];
+ static int relative = 1;
+
+ int i, nread;
+ int button = 0;
+ int dx = 0, dy = 0;
+ int packetsize = 0;
+ int realx, realy;
+
+ /* Figure out the mouse packet size */
+ switch (mouse_drv) {
+ case MOUSE_NONE:
+ break; /* carry on to read from device and discard it. */
+ case MOUSE_MSC:
+ packetsize = 5;
+ break;
+ case MOUSE_IMPS2:
+ packetsize = 4;
+ break;
+ case MOUSE_PS2:
+ case MOUSE_MS:
+ case MOUSE_BM:
+ packetsize = 3;
+ break;
+ case MOUSE_ELO:
+ /* try to read the next packet */
+ if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) {
+ button = (button & 0x01) << 2;
+ FB_vgamousecallback(button, 0, dx, dy);
+ }
+ return; /* nothing left to do */
+ case MOUSE_TSLIB:
+#if SDL_INPUT_TSLIB
+ handle_tslib(this);
+#endif
+ return; /* nothing left to do */
+ default:
+ /* Uh oh.. */
+ packetsize = 0;
+ break;
+ }
+
+ /* Special handling for the quite sensitive ELO controller */
+ if (mouse_drv == MOUSE_ELO) {
+
+ }
+
+ /* Read as many packets as possible */
+ nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start);
+ if ( nread < 0 ) {
+ return;
+ }
+
+ if (mouse_drv == MOUSE_NONE) {
+ return; /* we're done; just draining the input queue. */
+ }
+
+ nread += start;
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start);
+#endif
+
+ for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) {
+ switch (mouse_drv) {
+ case MOUSE_NONE: /* shouldn't actually hit this. */
+ break; /* just throw everything away. */
+ case MOUSE_MSC:
+ /* MSC protocol has 0x80 in high byte */
+ if ( (mousebuf[i] & 0xF8) != 0x80 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (~mousebuf[i]) & 0x07;
+ dx = (signed char)(mousebuf[i+1]) +
+ (signed char)(mousebuf[i+3]);
+ dy = -((signed char)(mousebuf[i+2]) +
+ (signed char)(mousebuf[i+4]));
+ break;
+ case MOUSE_PS2:
+ /* PS/2 protocol has nothing in high byte */
+ if ( (mousebuf[i] & 0xC0) != 0 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
+ (mousebuf[i] & 0x02) >> 1 | /*Right*/
+ (mousebuf[i] & 0x01) << 2; /*Left*/
+ dx = (mousebuf[i] & 0x10) ?
+ mousebuf[i+1] - 256 : mousebuf[i+1];
+ dy = (mousebuf[i] & 0x20) ?
+ -(mousebuf[i+2] - 256) : -mousebuf[i+2];
+ break;
+ case MOUSE_IMPS2:
+ /* Get current mouse state */
+ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
+ (mousebuf[i] & 0x02) >> 1 | /*Right*/
+ (mousebuf[i] & 0x01) << 2 | /*Left*/
+ (mousebuf[i] & 0x40) >> 3 | /* 4 */
+ (mousebuf[i] & 0x80) >> 3; /* 5 */
+ dx = (mousebuf[i] & 0x10) ?
+ mousebuf[i+1] - 256 : mousebuf[i+1];
+ dy = (mousebuf[i] & 0x20) ?
+ -(mousebuf[i+2] - 256) : -mousebuf[i+2];
+ switch (mousebuf[i+3]&0x0F) {
+ case 0x0E: /* DX = +1 */
+ case 0x02: /* DX = -1 */
+ break;
+ case 0x0F: /* DY = +1 (map button 4) */
+ FB_vgamousecallback(button | (1<<3),
+ 1, 0, 0);
+ break;
+ case 0x01: /* DY = -1 (map button 5) */
+ FB_vgamousecallback(button | (1<<4),
+ 1, 0, 0);
+ break;
+ }
+ break;
+ case MOUSE_MS:
+ /* Microsoft protocol has 0x40 in high byte */
+ if ( (mousebuf[i] & 0x40) != 0x40 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = ((mousebuf[i] & 0x20) >> 3) |
+ ((mousebuf[i] & 0x10) >> 4);
+ dx = (signed char)(((mousebuf[i] & 0x03) << 6) |
+ (mousebuf[i + 1] & 0x3F));
+ dy = (signed char)(((mousebuf[i] & 0x0C) << 4) |
+ (mousebuf[i + 2] & 0x3F));
+ break;
+ case MOUSE_BM:
+ /* BusMouse protocol has 0xF8 in high byte */
+ if ( (mousebuf[i] & 0xF8) != 0x80 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (~mousebuf[i]) & 0x07;
+ dx = (signed char)mousebuf[i+1];
+ dy = -(signed char)mousebuf[i+2];
+ break;
+ default:
+ /* Uh oh.. */
+ dx = 0;
+ dy = 0;
+ break;
+ }
+ FB_vgamousecallback(button, relative, dx, dy);
+ }
+ if ( i < nread ) {
+ SDL_memcpy(mousebuf, &mousebuf[i], (nread-i));
+ start = (nread-i);
+ } else {
+ start = 0;
+ }
+ return;
+}
+
+/* Handle switching to another VC, returns when our VC is back */
+static void switch_vt_prep(_THIS)
+{
+ SDL_Surface *screen = SDL_VideoSurface;
+
+ SDL_PrivateAppActive(0, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS));
+
+ /* Save the contents of the screen, and go to text mode */
+ wait_idle(this);
+ screen_arealen = ((screen->h + (2*this->offset_y)) * screen->pitch);
+ screen_contents = (Uint8 *)SDL_malloc(screen_arealen);
+ if ( screen_contents ) {
+ SDL_memcpy(screen_contents, screen->pixels, screen_arealen);
+ }
+ FB_SavePaletteTo(this, 256, screen_palette);
+ ioctl(console_fd, FBIOGET_VSCREENINFO, &screen_vinfo);
+ ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
+ ioctl(keyboard_fd, VT_UNLOCKSWITCH, 1);
+}
+static void switch_vt_done(_THIS)
+{
+ SDL_Surface *screen = SDL_VideoSurface;
+
+ /* Restore graphics mode and the contents of the screen */
+ ioctl(keyboard_fd, VT_LOCKSWITCH, 1);
+ ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS);
+ ioctl(console_fd, FBIOPUT_VSCREENINFO, &screen_vinfo);
+ FB_RestorePaletteFrom(this, 256, screen_palette);
+ if ( screen_contents ) {
+ SDL_memcpy(screen->pixels, screen_contents, screen_arealen);
+ SDL_free(screen_contents);
+ screen_contents = NULL;
+ }
+
+ /* Get updates to the shadow surface while switched away */
+ if ( SDL_ShadowSurface ) {
+ SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0);
+ }
+
+ SDL_PrivateAppActive(1, (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS));
+}
+static void switch_vt(_THIS, unsigned short which)
+{
+ struct vt_stat vtstate;
+
+ /* Figure out whether or not we're switching to a new console */
+ if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) ||
+ (which == vtstate.v_active) ) {
+ return;
+ }
+
+ /* New console, switch to it */
+ SDL_mutexP(hw_lock);
+ switch_vt_prep(this);
+ if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) {
+ ioctl(keyboard_fd, VT_WAITACTIVE, which);
+ switched_away = 1;
+ } else {
+ switch_vt_done(this);
+ }
+ SDL_mutexV(hw_lock);
+}
+
+static void handle_keyboard(_THIS)
+{
+ unsigned char keybuf[BUFSIZ];
+ int i, nread;
+ int pressed;
+ int scancode;
+ SDL_keysym keysym;
+
+ nread = read(keyboard_fd, keybuf, BUFSIZ);
+ for ( i=0; i<nread; ++i ) {
+ scancode = keybuf[i] & 0x7F;
+ if ( keybuf[i] & 0x80 ) {
+ pressed = SDL_RELEASED;
+ } else {
+ pressed = SDL_PRESSED;
+ }
+ TranslateKey(scancode, &keysym);
+ /* Handle Ctrl-Alt-FN for vt switch */
+ switch (keysym.sym) {
+ case SDLK_F1:
+ case SDLK_F2:
+ case SDLK_F3:
+ case SDLK_F4:
+ case SDLK_F5:
+ case SDLK_F6:
+ case SDLK_F7:
+ case SDLK_F8:
+ case SDLK_F9:
+ case SDLK_F10:
+ case SDLK_F11:
+ case SDLK_F12:
+ if ( (SDL_GetModState() & KMOD_CTRL) &&
+ (SDL_GetModState() & KMOD_ALT) ) {
+ if ( pressed ) {
+ switch_vt(this, (keysym.sym-SDLK_F1)+1);
+ }
+ break;
+ }
+ /* Fall through to normal processing */
+ default:
+ posted += SDL_PrivateKeyboard(pressed, &keysym);
+ break;
+ }
+ }
+}
+
+void FB_PumpEvents(_THIS)
+{
+ fd_set fdset;
+ int max_fd;
+ static struct timeval zero;
+
+ do {
+ if ( switched_away ) {
+ struct vt_stat vtstate;
+
+ SDL_mutexP(hw_lock);
+ if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0) &&
+ vtstate.v_active == current_vt ) {
+ switched_away = 0;
+ switch_vt_done(this);
+ }
+ SDL_mutexV(hw_lock);
+ }
+
+ posted = 0;
+
+ FD_ZERO(&fdset);
+ max_fd = 0;
+ if ( keyboard_fd >= 0 ) {
+ FD_SET(keyboard_fd, &fdset);
+ if ( max_fd < keyboard_fd ) {
+ max_fd = keyboard_fd;
+ }
+ }
+ if ( mouse_fd >= 0 ) {
+ FD_SET(mouse_fd, &fdset);
+ if ( max_fd < mouse_fd ) {
+ max_fd = mouse_fd;
+ }
+ }
+ if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) {
+ if ( keyboard_fd >= 0 ) {
+ if ( FD_ISSET(keyboard_fd, &fdset) ) {
+ handle_keyboard(this);
+ }
+ }
+ if ( mouse_fd >= 0 ) {
+ if ( FD_ISSET(mouse_fd, &fdset) ) {
+ handle_mouse(this);
+ }
+ }
+ }
+ } while ( posted );
+}
+
+void FB_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the Linux key translation table */
+
+ /* First get the ascii keys and others not well handled */
+ for (i=0; i<SDL_arraysize(keymap); ++i) {
+ switch(i) {
+ /* These aren't handled by the x86 kernel keymapping (?) */
+ case SCANCODE_PRINTSCREEN:
+ keymap[i] = SDLK_PRINT;
+ break;
+ case SCANCODE_BREAK:
+ keymap[i] = SDLK_BREAK;
+ break;
+ case SCANCODE_BREAK_ALTERNATIVE:
+ keymap[i] = SDLK_PAUSE;
+ break;
+ case SCANCODE_LEFTSHIFT:
+ keymap[i] = SDLK_LSHIFT;
+ break;
+ case SCANCODE_RIGHTSHIFT:
+ keymap[i] = SDLK_RSHIFT;
+ break;
+ case SCANCODE_LEFTCONTROL:
+ keymap[i] = SDLK_LCTRL;
+ break;
+ case SCANCODE_RIGHTCONTROL:
+ keymap[i] = SDLK_RCTRL;
+ break;
+ case SCANCODE_RIGHTWIN:
+ keymap[i] = SDLK_RSUPER;
+ break;
+ case SCANCODE_LEFTWIN:
+ keymap[i] = SDLK_LSUPER;
+ break;
+ case SCANCODE_LEFTALT:
+ keymap[i] = SDLK_LALT;
+ break;
+ case SCANCODE_RIGHTALT:
+ keymap[i] = SDLK_RALT;
+ break;
+ case 127:
+ keymap[i] = SDLK_MENU;
+ break;
+ /* this should take care of all standard ascii keys */
+ default:
+ keymap[i] = KVAL(vga_keymap[0][i]);
+ break;
+ }
+ }
+ for (i=0; i<SDL_arraysize(keymap); ++i) {
+ switch(keymap_temp[i]) {
+ case K_F1: keymap[i] = SDLK_F1; break;
+ case K_F2: keymap[i] = SDLK_F2; break;
+ case K_F3: keymap[i] = SDLK_F3; break;
+ case K_F4: keymap[i] = SDLK_F4; break;
+ case K_F5: keymap[i] = SDLK_F5; break;
+ case K_F6: keymap[i] = SDLK_F6; break;
+ case K_F7: keymap[i] = SDLK_F7; break;
+ case K_F8: keymap[i] = SDLK_F8; break;
+ case K_F9: keymap[i] = SDLK_F9; break;
+ case K_F10: keymap[i] = SDLK_F10; break;
+ case K_F11: keymap[i] = SDLK_F11; break;
+ case K_F12: keymap[i] = SDLK_F12; break;
+
+ case K_DOWN: keymap[i] = SDLK_DOWN; break;
+ case K_LEFT: keymap[i] = SDLK_LEFT; break;
+ case K_RIGHT: keymap[i] = SDLK_RIGHT; break;
+ case K_UP: keymap[i] = SDLK_UP; break;
+
+ case K_P0: keymap[i] = SDLK_KP0; break;
+ case K_P1: keymap[i] = SDLK_KP1; break;
+ case K_P2: keymap[i] = SDLK_KP2; break;
+ case K_P3: keymap[i] = SDLK_KP3; break;
+ case K_P4: keymap[i] = SDLK_KP4; break;
+ case K_P5: keymap[i] = SDLK_KP5; break;
+ case K_P6: keymap[i] = SDLK_KP6; break;
+ case K_P7: keymap[i] = SDLK_KP7; break;
+ case K_P8: keymap[i] = SDLK_KP8; break;
+ case K_P9: keymap[i] = SDLK_KP9; break;
+ case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break;
+ case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break;
+ case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break;
+ case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break;
+ case K_PENTER: keymap[i] = SDLK_KP_ENTER; break;
+ case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break;
+
+ case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT )
+ keymap[i] = SDLK_LSHIFT;
+ break;
+ case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break;
+ case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break;
+ case K_CTRL: if ( keymap[i] != SDLK_RCTRL )
+ keymap[i] = SDLK_LCTRL;
+ break;
+ case K_CTRLL: keymap[i] = SDLK_LCTRL; break;
+ case K_CTRLR: keymap[i] = SDLK_RCTRL; break;
+ case K_ALT: keymap[i] = SDLK_LALT; break;
+ case K_ALTGR: keymap[i] = SDLK_RALT; break;
+
+ case K_INSERT: keymap[i] = SDLK_INSERT; break;
+ case K_REMOVE: keymap[i] = SDLK_DELETE; break;
+ case K_PGUP: keymap[i] = SDLK_PAGEUP; break;
+ case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break;
+ case K_FIND: keymap[i] = SDLK_HOME; break;
+ case K_SELECT: keymap[i] = SDLK_END; break;
+
+ case K_NUM: keymap[i] = SDLK_NUMLOCK; break;
+ case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break;
+
+ case K_F13: keymap[i] = SDLK_PRINT; break;
+ case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break;
+ case K_PAUSE: keymap[i] = SDLK_PAUSE; break;
+
+ case 127: keymap[i] = SDLK_BACKSPACE; break;
+
+ default: break;
+ }
+ }
+}
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE ) {
+ int map;
+ SDLMod modstate;
+
+ modstate = SDL_GetModState();
+ map = 0;
+ if ( modstate & KMOD_SHIFT ) {
+ map |= (1<<KG_SHIFT);
+ }
+ if ( modstate & KMOD_CTRL ) {
+ map |= (1<<KG_CTRL);
+ }
+ if ( modstate & KMOD_LALT ) {
+ map |= (1<<KG_ALT);
+ }
+ if ( modstate & KMOD_RALT ) {
+ map |= (1<<KG_ALTGR);
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) {
+ if ( modstate & KMOD_CAPS ) {
+ map ^= (1<<KG_SHIFT);
+ }
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) {
+ if ( modstate & KMOD_NUM ) {
+ keysym->unicode=KVAL(vga_keymap[map][scancode]);
+ }
+ } else {
+ keysym->unicode = KVAL(vga_keymap[map][scancode]);
+ }
+ }
+ return(keysym);
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents_c.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents_c.h
new file mode 100644
index 0000000..fe8b09c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbevents_c.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_fbvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern int FB_OpenKeyboard(_THIS);
+extern void FB_CloseKeyboard(_THIS);
+extern int FB_OpenMouse(_THIS);
+extern void FB_CloseMouse(_THIS);
+extern int FB_EnterGraphicsMode(_THIS);
+extern int FB_InGraphicsMode(_THIS);
+extern void FB_LeaveGraphicsMode(_THIS);
+
+extern void FB_InitOSKeymap(_THIS);
+extern void FB_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbkeys.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbkeys.h
new file mode 100644
index 0000000..2b01b6b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbkeys.h
@@ -0,0 +1,139 @@
+
+/* Scancodes for the Linux framebuffer console
+ - Taken with thanks from SVGAlib 1.4.0
+*/
+
+#define SCANCODE_ESCAPE 1
+
+#define SCANCODE_1 2
+#define SCANCODE_2 3
+#define SCANCODE_3 4
+#define SCANCODE_4 5
+#define SCANCODE_5 6
+#define SCANCODE_6 7
+#define SCANCODE_7 8
+#define SCANCODE_8 9
+#define SCANCODE_9 10
+#define SCANCODE_0 11
+
+#define SCANCODE_MINUS 12
+#define SCANCODE_EQUAL 13
+
+#define SCANCODE_BACKSPACE 14
+#define SCANCODE_TAB 15
+
+#define SCANCODE_Q 16
+#define SCANCODE_W 17
+#define SCANCODE_E 18
+#define SCANCODE_R 19
+#define SCANCODE_T 20
+#define SCANCODE_Y 21
+#define SCANCODE_U 22
+#define SCANCODE_I 23
+#define SCANCODE_O 24
+#define SCANCODE_P 25
+#define SCANCODE_BRACKET_LEFT 26
+#define SCANCODE_BRACKET_RIGHT 27
+
+#define SCANCODE_ENTER 28
+
+#define SCANCODE_LEFTCONTROL 29
+
+#define SCANCODE_A 30
+#define SCANCODE_S 31
+#define SCANCODE_D 32
+#define SCANCODE_F 33
+#define SCANCODE_G 34
+#define SCANCODE_H 35
+#define SCANCODE_J 36
+#define SCANCODE_K 37
+#define SCANCODE_L 38
+#define SCANCODE_SEMICOLON 39
+#define SCANCODE_APOSTROPHE 40
+#define SCANCODE_GRAVE 41
+
+#define SCANCODE_LEFTSHIFT 42
+#define SCANCODE_BACKSLASH 43
+
+#define SCANCODE_Z 44
+#define SCANCODE_X 45
+#define SCANCODE_C 46
+#define SCANCODE_V 47
+#define SCANCODE_B 48
+#define SCANCODE_N 49
+#define SCANCODE_M 50
+#define SCANCODE_COMMA 51
+#define SCANCODE_PERIOD 52
+#define SCANCODE_SLASH 53
+
+#define SCANCODE_RIGHTSHIFT 54
+#define SCANCODE_KEYPADMULTIPLY 55
+
+#define SCANCODE_LEFTALT 56
+#define SCANCODE_SPACE 57
+#define SCANCODE_CAPSLOCK 58
+
+#define SCANCODE_F1 59
+#define SCANCODE_F2 60
+#define SCANCODE_F3 61
+#define SCANCODE_F4 62
+#define SCANCODE_F5 63
+#define SCANCODE_F6 64
+#define SCANCODE_F7 65
+#define SCANCODE_F8 66
+#define SCANCODE_F9 67
+#define SCANCODE_F10 68
+
+#define SCANCODE_NUMLOCK 69
+#define SCANCODE_SCROLLLOCK 70
+
+#define SCANCODE_KEYPAD7 71
+#define SCANCODE_CURSORUPLEFT 71
+#define SCANCODE_KEYPAD8 72
+#define SCANCODE_CURSORUP 72
+#define SCANCODE_KEYPAD9 73
+#define SCANCODE_CURSORUPRIGHT 73
+#define SCANCODE_KEYPADMINUS 74
+#define SCANCODE_KEYPAD4 75
+#define SCANCODE_CURSORLEFT 75
+#define SCANCODE_KEYPAD5 76
+#define SCANCODE_KEYPAD6 77
+#define SCANCODE_CURSORRIGHT 77
+#define SCANCODE_KEYPADPLUS 78
+#define SCANCODE_KEYPAD1 79
+#define SCANCODE_CURSORDOWNLEFT 79
+#define SCANCODE_KEYPAD2 80
+#define SCANCODE_CURSORDOWN 80
+#define SCANCODE_KEYPAD3 81
+#define SCANCODE_CURSORDOWNRIGHT 81
+#define SCANCODE_KEYPAD0 82
+#define SCANCODE_KEYPADPERIOD 83
+
+#define SCANCODE_LESS 86
+
+#define SCANCODE_F11 87
+#define SCANCODE_F12 88
+
+#define SCANCODE_KEYPADENTER 96
+#define SCANCODE_RIGHTCONTROL 97
+#define SCANCODE_CONTROL 97
+#define SCANCODE_KEYPADDIVIDE 98
+#define SCANCODE_PRINTSCREEN 99
+#define SCANCODE_RIGHTALT 100
+#define SCANCODE_BREAK 101 /* Beware: is 119 */
+#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
+
+#define SCANCODE_HOME 102
+#define SCANCODE_CURSORBLOCKUP 103 /* Cursor key block */
+#define SCANCODE_PAGEUP 104
+#define SCANCODE_CURSORBLOCKLEFT 105 /* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT 106 /* Cursor key block */
+#define SCANCODE_END 107
+#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
+#define SCANCODE_PAGEDOWN 109
+#define SCANCODE_INSERT 110
+#define SCANCODE_REMOVE 111
+
+#define SCANCODE_RIGHTWIN 126
+#define SCANCODE_LEFTWIN 125
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.c
new file mode 100644
index 0000000..04b90b0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.c
@@ -0,0 +1,280 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "../SDL_blit.h"
+#include "SDL_fbmatrox.h"
+#include "matrox_mmio.h"
+
+
+/* Wait for vertical retrace - taken from the XFree86 Matrox driver */
+static void WaitVBL(_THIS)
+{
+ int count;
+
+ /* find start of retrace */
+ mga_waitidle();
+ while ( (mga_in8(0x1FDA) & 0x08) )
+ ;
+ while ( !(mga_in8(0x1FDA) & 0x08) )
+ ;
+ /* wait until we're past the start */
+ count = mga_in32(0x1E20) + 2;
+ while ( mga_in32(0x1E20) < count )
+ ;
+}
+static void WaitIdle(_THIS)
+{
+ mga_waitidle();
+}
+
+/* Sets video mem colorkey and accelerated blit function */
+static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ return(0);
+}
+
+/* Sets per surface hardware alpha value */
+#if 0
+static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value)
+{
+ return(0);
+}
+#endif
+
+static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
+{
+ int dstX, dstY;
+ Uint32 fxbndry;
+ Uint32 ydstlen;
+ Uint32 fillop;
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ switch (dst->format->BytesPerPixel) {
+ case 1:
+ color |= (color<<8);
+ case 2:
+ color |= (color<<16);
+ break;
+ }
+
+ /* Set up the X/Y base coordinates */
+ FB_dst_to_xy(this, dst, &dstX, &dstY);
+
+ /* Adjust for the current rectangle */
+ dstX += rect->x;
+ dstY += rect->y;
+
+ /* Set up the X boundaries */
+ fxbndry = (dstX | ((dstX+rect->w) << 16));
+
+ /* Set up the Y boundaries */
+ ydstlen = (rect->h | (dstY << 16));
+
+ /* Set up for color fill operation */
+ fillop = MGADWG_TRAP | MGADWG_SOLID |
+ MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
+
+ /* Execute the operations! */
+ mga_wait(5);
+ mga_out32(MGAREG_DWGCTL, fillop | MGADWG_REPLACE);
+ mga_out32(MGAREG_FCOL, color);
+ mga_out32(MGAREG_FXBNDRY, fxbndry);
+ mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
+
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_VideoDevice *this = current_video;
+ int pitch, w, h;
+ int srcX, srcY;
+ int dstX, dstY;
+ Uint32 sign;
+ Uint32 start, stop;
+ int skip;
+ Uint32 blitop;
+
+ /* FIXME: For now, only blit to display surface */
+ if ( dst->pitch != SDL_VideoSurface->pitch ) {
+ return(src->map->sw_blit(src, srcrect, dst, dstrect));
+ }
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ /* Calculate source and destination base coordinates (in pixels) */
+ w = dstrect->w;
+ h = dstrect->h;
+ FB_dst_to_xy(this, src, &srcX, &srcY);
+ FB_dst_to_xy(this, dst, &dstX, &dstY);
+
+ /* Adjust for the current blit rectangles */
+ srcX += srcrect->x;
+ srcY += srcrect->y;
+ dstX += dstrect->x;
+ dstY += dstrect->y;
+ pitch = dst->pitch/dst->format->BytesPerPixel;
+
+ /* Set up the blit direction (sign) flags */
+ sign = 0;
+ if ( srcX < dstX ) {
+ sign |= 1;
+ }
+ if ( srcY < dstY ) {
+ sign |= 4;
+ srcY += (h - 1);
+ dstY += (h - 1);
+ }
+
+ /* Set up the blit source row start, end, and skip (in pixels) */
+ stop = start = (srcY * pitch) + srcX;
+ if ( srcX < dstX ) {
+ start += (w - 1);
+ } else {
+ stop += (w - 1);
+ }
+ if ( srcY < dstY ) {
+ skip = -pitch;
+ } else {
+ skip = pitch;
+ }
+
+ /* Set up the blit operation */
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ Uint32 colorkey;
+
+ blitop = MGADWG_BFCOL | MGADWG_BITBLT |
+ MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16) |
+ MGADWG_TRANSC;
+
+ colorkey = src->format->colorkey;
+ switch (dst->format->BytesPerPixel) {
+ case 1:
+ colorkey |= (colorkey<<8);
+ case 2:
+ colorkey |= (colorkey<<16);
+ break;
+ }
+ mga_wait(2);
+ mga_out32(MGAREG_FCOL, colorkey);
+ mga_out32(MGAREG_BCOL, 0xFFFFFFFF);
+ } else {
+ blitop = MGADWG_BFCOL | MGADWG_BITBLT |
+ MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16);
+ }
+ mga_wait(7);
+ mga_out32(MGAREG_SGN, sign);
+ mga_out32(MGAREG_AR3, start);
+ mga_out32(MGAREG_AR0, stop);
+ mga_out32(MGAREG_AR5, skip);
+ mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w-1) << 16)));
+ mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h);
+ mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
+
+ FB_AddBusySurface(src);
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ int accelerated;
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! this->info.blit_hw_A ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! this->info.blit_hw_CC ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+ src->map->hw_blit = HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+void FB_MatroxAccel(_THIS, __u32 card)
+{
+ /* We have hardware accelerated surface functions */
+ this->CheckHWBlit = CheckHWBlit;
+ wait_vbl = WaitVBL;
+ wait_idle = WaitIdle;
+
+ /* The Matrox has an accelerated color fill */
+ this->info.blit_fill = 1;
+ this->FillHWRect = FillHWRect;
+
+ /* The Matrox has accelerated normal and colorkey blits. */
+ this->info.blit_hw = 1;
+ /* The Millenium I appears to do the colorkey test a word
+ at a time, and the transparency is intverted. (?)
+ */
+ if ( card != FB_ACCEL_MATROX_MGA2064W ) {
+ this->info.blit_hw_CC = 1;
+ this->SetHWColorKey = SetHWColorKey;
+ }
+
+#if 0 /* Not yet implemented? */
+ /* The Matrox G200/G400 has an accelerated alpha blit */
+ if ( (card == FB_ACCEL_MATROX_MGAG200)
+ || (card == FB_ACCEL_MATROX_MGAG400)
+ ) {
+ this->info.blit_hw_A = 1;
+ this->SetHWAlpha = SetHWAlpha;
+ }
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.h
new file mode 100644
index 0000000..f7d41b0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmatrox.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Matrox hardware acceleration for the SDL framebuffer console driver */
+
+#include "SDL_fbvideo.h"
+
+/* Set up the driver for Matrox acceleration */
+extern void FB_MatroxAccel(_THIS, __u32 card);
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse.c
new file mode 100644
index 0000000..d65f27e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse.c
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_fbvideo.h"
+#include "SDL_fbmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse_c.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse_c.h
new file mode 100644
index 0000000..fbb031d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbmouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_fbvideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.c
new file mode 100644
index 0000000..eb4b71f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.c
@@ -0,0 +1,222 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_video.h"
+#include "../SDL_blit.h"
+#include "SDL_fbriva.h"
+#include "riva_mmio.h"
+#include "riva_regs.h"
+
+
+static int FifoEmptyCount = 0;
+static int FifoFreeCount = 0;
+
+/* Wait for vertical retrace */
+static void WaitVBL(_THIS)
+{
+ volatile Uint8 *port = (Uint8 *)(mapped_io + PCIO_OFFSET + 0x3DA);
+
+ while ( (*port & 0x08) )
+ ;
+ while ( !(*port & 0x08) )
+ ;
+}
+static void NV3WaitIdle(_THIS)
+{
+ RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET);
+ while ( (Rop->FifoFree < FifoEmptyCount) ||
+ (*(mapped_io + PGRAPH_OFFSET + 0x000006B0) & 0x01) )
+ ;
+}
+static void NV4WaitIdle(_THIS)
+{
+ RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET);
+ while ( (Rop->FifoFree < FifoEmptyCount) ||
+ (*(mapped_io + PGRAPH_OFFSET + 0x00000700) & 0x01) )
+ ;
+}
+
+#if 0 /* Not yet implemented? */
+/* Sets video mem colorkey and accelerated blit function */
+static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ return(0);
+}
+
+/* Sets per surface hardware alpha value */
+static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value)
+{
+ return(0);
+}
+#endif /* Not yet implemented */
+
+static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
+{
+ int dstX, dstY;
+ int dstW, dstH;
+ RivaBitmap *Bitmap = (RivaBitmap *)(mapped_io + BITMAP_OFFSET);
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ /* Set up the X/Y base coordinates */
+ dstW = rect->w;
+ dstH = rect->h;
+ FB_dst_to_xy(this, dst, &dstX, &dstY);
+
+ /* Adjust for the current rectangle */
+ dstX += rect->x;
+ dstY += rect->y;
+
+ RIVA_FIFO_FREE(Bitmap, 1);
+ Bitmap->Color1A = color;
+
+ RIVA_FIFO_FREE(Bitmap, 2);
+ Bitmap->UnclippedRectangle[0].TopLeft = (dstX << 16) | dstY;
+ Bitmap->UnclippedRectangle[0].WidthHeight = (dstW << 16) | dstH;
+
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ SDL_VideoDevice *this = current_video;
+ int srcX, srcY;
+ int dstX, dstY;
+ int dstW, dstH;
+ RivaScreenBlt *Blt = (RivaScreenBlt *)(mapped_io + BLT_OFFSET);
+
+ /* FIXME: For now, only blit to display surface */
+ if ( dst->pitch != SDL_VideoSurface->pitch ) {
+ return(src->map->sw_blit(src, srcrect, dst, dstrect));
+ }
+
+ /* Don't blit to the display surface when switched away */
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( dst == this->screen ) {
+ SDL_mutexP(hw_lock);
+ }
+
+ /* Calculate source and destination base coordinates (in pixels) */
+ dstW = dstrect->w;
+ dstH = dstrect->h;
+ FB_dst_to_xy(this, src, &srcX, &srcY);
+ FB_dst_to_xy(this, dst, &dstX, &dstY);
+
+ /* Adjust for the current blit rectangles */
+ srcX += srcrect->x;
+ srcY += srcrect->y;
+ dstX += dstrect->x;
+ dstY += dstrect->y;
+
+ RIVA_FIFO_FREE(Blt, 3);
+ Blt->TopLeftSrc = (srcY << 16) | srcX;
+ Blt->TopLeftDst = (dstY << 16) | dstX;
+ Blt->WidthHeight = (dstH << 16) | dstW;
+
+ FB_AddBusySurface(src);
+ FB_AddBusySurface(dst);
+
+ if ( dst == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+ return(0);
+}
+
+static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ int accelerated;
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! this->info.blit_hw_A ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! this->info.blit_hw_CC ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+ src->map->hw_blit = HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+void FB_RivaAccel(_THIS, __u32 card)
+{
+ RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET);
+
+ /* We have hardware accelerated surface functions */
+ this->CheckHWBlit = CheckHWBlit;
+ wait_vbl = WaitVBL;
+ switch (card) {
+ case FB_ACCEL_NV3:
+ wait_idle = NV3WaitIdle;
+ break;
+ case FB_ACCEL_NV4:
+ wait_idle = NV4WaitIdle;
+ break;
+ default:
+ /* Hmm... FIXME */
+ break;
+ }
+ FifoEmptyCount = Rop->FifoFree;
+
+ /* The Riva has an accelerated color fill */
+ this->info.blit_fill = 1;
+ this->FillHWRect = FillHWRect;
+
+ /* The Riva has accelerated normal and colorkey blits. */
+ this->info.blit_hw = 1;
+#if 0 /* Not yet implemented? */
+ this->info.blit_hw_CC = 1;
+ this->SetHWColorKey = SetHWColorKey;
+#endif
+
+#if 0 /* Not yet implemented? */
+ /* The Riva has an accelerated alpha blit */
+ this->info.blit_hw_A = 1;
+ this->SetHWAlpha = SetHWAlpha;
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.h
new file mode 100644
index 0000000..c78682e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbriva.h
@@ -0,0 +1,36 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Riva hardware acceleration for the SDL framebuffer console driver */
+
+#include "SDL_fbvideo.h"
+
+#ifndef FB_ACCEL_NV3
+#define FB_ACCEL_NV3 27
+#endif
+#ifndef FB_ACCEL_NV4
+#define FB_ACCEL_NV4 28
+#endif
+
+/* Set up the driver for Riva acceleration */
+extern void FB_RivaAccel(_THIS, __u32 card);
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.c b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.c
new file mode 100644
index 0000000..5e58809
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.c
@@ -0,0 +1,1982 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Framebuffer console based SDL video driver implementation.
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#ifndef HAVE_GETPAGESIZE
+#include <asm/page.h> /* For definition of PAGE_SIZE */
+#endif
+
+#include <linux/vt.h>
+
+#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_fbvideo.h"
+#include "SDL_fbmouse_c.h"
+#include "SDL_fbevents_c.h"
+#include "SDL_fb3dfx.h"
+#include "SDL_fbmatrox.h"
+#include "SDL_fbriva.h"
+
+/*#define FBCON_DEBUG*/
+
+#if defined(i386) && defined(FB_TYPE_VGA_PLANES)
+#define VGA16_FBCON_SUPPORT
+#include <sys/io.h> /* For ioperm() */
+#ifndef FB_AUX_VGA_PLANES_VGA4
+#define FB_AUX_VGA_PLANES_VGA4 0
+#endif
+/*
+static inline void outb (unsigned char value, unsigned short port)
+{
+ __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port));
+}
+*/
+#endif /* FB_TYPE_VGA_PLANES */
+
+/* A list of video resolutions that we query for (sorted largest to smallest) */
+static const SDL_Rect checkres[] = {
+ { 0, 0, 1600, 1200 }, /* 16 bpp: 0x11E, or 286 */
+ { 0, 0, 1408, 1056 }, /* 16 bpp: 0x19A, or 410 */
+ { 0, 0, 1280, 1024 }, /* 16 bpp: 0x11A, or 282 */
+ { 0, 0, 1152, 864 }, /* 16 bpp: 0x192, or 402 */
+ { 0, 0, 1024, 768 }, /* 16 bpp: 0x117, or 279 */
+ { 0, 0, 960, 720 }, /* 16 bpp: 0x18A, or 394 */
+ { 0, 0, 800, 600 }, /* 16 bpp: 0x114, or 276 */
+ { 0, 0, 768, 576 }, /* 16 bpp: 0x182, or 386 */
+ { 0, 0, 720, 576 }, /* PAL */
+ { 0, 0, 720, 480 }, /* NTSC */
+ { 0, 0, 640, 480 }, /* 16 bpp: 0x111, or 273 */
+ { 0, 0, 640, 400 }, /* 8 bpp: 0x100, or 256 */
+ { 0, 0, 512, 384 },
+ { 0, 0, 320, 240 },
+ { 0, 0, 320, 200 }
+};
+static const struct {
+ int xres;
+ int yres;
+ int pixclock;
+ int left;
+ int right;
+ int upper;
+ int lower;
+ int hslen;
+ int vslen;
+ int sync;
+ int vmode;
+} vesa_timings[] = {
+#ifdef USE_VESA_TIMINGS /* Only tested on Matrox Millenium I */
+ { 640, 400, 39771, 48, 16, 39, 8, 96, 2, 2, 0 }, /* 70 Hz */
+ { 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0, 0 }, /* 60 Hz */
+ { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */
+ { 800, 600, 24038, 144, 24, 28, 8, 112, 6, 0, 0 }, /* 60 Hz */
+ { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */
+ { 1024, 768, 15386, 160, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */
+ { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */
+ { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */
+ { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */
+ { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */
+#else
+ /* You can generate these timings from your XF86Config file using
+ the 'modeline2fb' perl script included with the fbset package.
+ These timings were generated for Matrox Millenium I, 15" monitor.
+ */
+ { 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0, 2 }, /* 70 Hz */
+ { 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0, 2 }, /* 72 Hz */
+ { 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0, 0 }, /* 78 Hz */
+ { 640, 400, 31746, 96, 32, 41, 1, 64, 3, 2, 0 }, /* 85 Hz */
+ { 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0 }, /* 75 Hz */
+ { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */
+ { 800, 600, 20000, 64, 56, 23, 37, 120, 6, 3, 0 }, /* 72 Hz */
+ { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */
+ { 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0, 0 }, /* 70 Hz */
+ { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */
+ { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */
+ { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */
+ { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */
+#endif
+};
+enum {
+ FBCON_ROTATE_NONE = 0,
+ FBCON_ROTATE_CCW = 90,
+ FBCON_ROTATE_UD = 180,
+ FBCON_ROTATE_CW = 270
+};
+
+#define min(a,b) ((a)<(b)?(a):(b))
+
+/* Initialization/Query functions */
+static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+#ifdef VGA16_FBCON_SUPPORT
+static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+#endif
+static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void FB_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size);
+static void FB_FreeHWSurfaces(_THIS);
+static int FB_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int FB_LockHWSurface(_THIS, SDL_Surface *surface);
+static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void FB_FreeHWSurface(_THIS, SDL_Surface *surface);
+static void FB_WaitVBL(_THIS);
+static void FB_WaitIdle(_THIS);
+static int FB_FlipHWSurface(_THIS, SDL_Surface *surface);
+
+/* Internal palette functions */
+static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo,
+ struct fb_var_screeninfo *vinfo);
+static void FB_RestorePalette(_THIS);
+
+/* Shadow buffer functions */
+static FB_bitBlit FB_blit16;
+static FB_bitBlit FB_blit16blocked;
+
+static int SDL_getpagesize(void)
+{
+#ifdef HAVE_GETPAGESIZE
+ return getpagesize();
+#elif defined(PAGE_SIZE)
+ return PAGE_SIZE;
+#else
+#error Can not determine system page size.
+ return 4096; /* this is what it USED to be in Linux... */
+#endif
+}
+
+
+/* Small wrapper for mmap() so we can play nicely with no-mmu hosts
+ * (non-mmu hosts disallow the MAP_SHARED flag) */
+
+static void *do_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ void *ret;
+ ret = mmap(start, length, prot, flags, fd, offset);
+ if ( ret == (char *)-1 && (flags & MAP_SHARED) ) {
+ ret = mmap(start, length, prot,
+ (flags & ~MAP_SHARED) | MAP_PRIVATE, fd, offset);
+ }
+ return ret;
+}
+
+/* FB driver bootstrap functions */
+
+static int FB_Available(void)
+{
+ int console = -1;
+ /* Added check for /fb/0 (devfs) */
+ /* but - use environment variable first... if it fails, still check defaults */
+ int idx = 0;
+ const char *SDL_fbdevs[4] = { NULL, "/dev/fb0", "/dev/fb/0", NULL };
+
+ SDL_fbdevs[0] = SDL_getenv("SDL_FBDEV");
+ if( !SDL_fbdevs[0] )
+ idx++;
+ for( ; SDL_fbdevs[idx]; idx++ )
+ {
+ console = open(SDL_fbdevs[idx], O_RDWR, 0);
+ if ( console >= 0 ) {
+ close(console);
+ break;
+ }
+ }
+ return(console >= 0);
+}
+
+static void FB_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *FB_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *this;
+
+ /* Initialize all variables that we clean on shutdown */
+ this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( this ) {
+ SDL_memset(this, 0, (sizeof *this));
+ this->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *this->hidden));
+ }
+ if ( (this == NULL) || (this->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( this ) {
+ SDL_free(this);
+ }
+ return(0);
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+ wait_vbl = FB_WaitVBL;
+ wait_idle = FB_WaitIdle;
+ mouse_fd = -1;
+ keyboard_fd = -1;
+
+ /* Set the function pointers */
+ this->VideoInit = FB_VideoInit;
+ this->ListModes = FB_ListModes;
+ this->SetVideoMode = FB_SetVideoMode;
+ this->SetColors = FB_SetColors;
+ this->UpdateRects = NULL;
+ this->VideoQuit = FB_VideoQuit;
+ this->AllocHWSurface = FB_AllocHWSurface;
+ this->CheckHWBlit = NULL;
+ this->FillHWRect = NULL;
+ this->SetHWColorKey = NULL;
+ this->SetHWAlpha = NULL;
+ this->LockHWSurface = FB_LockHWSurface;
+ this->UnlockHWSurface = FB_UnlockHWSurface;
+ this->FlipHWSurface = FB_FlipHWSurface;
+ this->FreeHWSurface = FB_FreeHWSurface;
+ this->SetCaption = NULL;
+ this->SetIcon = NULL;
+ this->IconifyWindow = NULL;
+ this->GrabInput = NULL;
+ this->GetWMInfo = NULL;
+ this->InitOSKeymap = FB_InitOSKeymap;
+ this->PumpEvents = FB_PumpEvents;
+
+ this->free = FB_DeleteDevice;
+
+ return this;
+}
+
+VideoBootStrap FBCON_bootstrap = {
+ "fbcon", "Linux Framebuffer Console",
+ FB_Available, FB_CreateDevice
+};
+
+#define FB_MODES_DB "/etc/fb.modes"
+
+static int read_fbmodes_line(FILE*f, char* line, int length)
+{
+ int blank;
+ char* c;
+ int i;
+
+ blank=0;
+ /* find a relevant line */
+ do
+ {
+ if (!fgets(line,length,f))
+ return 0;
+ c=line;
+ while(((*c=='\t')||(*c==' '))&&(*c!=0))
+ c++;
+
+ if ((*c=='\n')||(*c=='#')||(*c==0))
+ blank=1;
+ else
+ blank=0;
+ }
+ while(blank);
+ /* remove whitespace at the begining of the string */
+ i=0;
+ do
+ {
+ line[i]=c[i];
+ i++;
+ }
+ while(c[i]!=0);
+ return 1;
+}
+
+static int read_fbmodes_mode(FILE *f, struct fb_var_screeninfo *vinfo)
+{
+ char line[1024];
+ char option[256];
+
+ /* Find a "geometry" */
+ do {
+ if (read_fbmodes_line(f, line, sizeof(line))==0)
+ return 0;
+ if (SDL_strncmp(line,"geometry",8)==0)
+ break;
+ }
+ while(1);
+
+ SDL_sscanf(line, "geometry %d %d %d %d %d", &vinfo->xres, &vinfo->yres,
+ &vinfo->xres_virtual, &vinfo->yres_virtual, &vinfo->bits_per_pixel);
+ if (read_fbmodes_line(f, line, sizeof(line))==0)
+ return 0;
+
+ SDL_sscanf(line, "timings %d %d %d %d %d %d %d", &vinfo->pixclock,
+ &vinfo->left_margin, &vinfo->right_margin, &vinfo->upper_margin,
+ &vinfo->lower_margin, &vinfo->hsync_len, &vinfo->vsync_len);
+
+ vinfo->sync=0;
+ vinfo->vmode=FB_VMODE_NONINTERLACED;
+
+ /* Parse misc options */
+ do {
+ if (read_fbmodes_line(f, line, sizeof(line))==0)
+ return 0;
+
+ if (SDL_strncmp(line,"hsync",5)==0) {
+ SDL_sscanf(line,"hsync %s",option);
+ if (SDL_strncmp(option,"high",4)==0)
+ vinfo->sync |= FB_SYNC_HOR_HIGH_ACT;
+ }
+ else if (SDL_strncmp(line,"vsync",5)==0) {
+ SDL_sscanf(line,"vsync %s",option);
+ if (SDL_strncmp(option,"high",4)==0)
+ vinfo->sync |= FB_SYNC_VERT_HIGH_ACT;
+ }
+ else if (SDL_strncmp(line,"csync",5)==0) {
+ SDL_sscanf(line,"csync %s",option);
+ if (SDL_strncmp(option,"high",4)==0)
+ vinfo->sync |= FB_SYNC_COMP_HIGH_ACT;
+ }
+ else if (SDL_strncmp(line,"extsync",5)==0) {
+ SDL_sscanf(line,"extsync %s",option);
+ if (SDL_strncmp(option,"true",4)==0)
+ vinfo->sync |= FB_SYNC_EXT;
+ }
+ else if (SDL_strncmp(line,"laced",5)==0) {
+ SDL_sscanf(line,"laced %s",option);
+ if (SDL_strncmp(option,"true",4)==0)
+ vinfo->vmode |= FB_VMODE_INTERLACED;
+ }
+ else if (SDL_strncmp(line,"double",6)==0) {
+ SDL_sscanf(line,"double %s",option);
+ if (SDL_strncmp(option,"true",4)==0)
+ vinfo->vmode |= FB_VMODE_DOUBLE;
+ }
+ }
+ while(SDL_strncmp(line,"endmode",7)!=0);
+
+ return 1;
+}
+
+static int FB_CheckMode(_THIS, struct fb_var_screeninfo *vinfo,
+ int index, unsigned int *w, unsigned int *h)
+{
+ int mode_okay;
+
+ mode_okay = 0;
+ vinfo->bits_per_pixel = (index+1)*8;
+ vinfo->xres = *w;
+ vinfo->xres_virtual = *w;
+ vinfo->yres = *h;
+ vinfo->yres_virtual = *h;
+ vinfo->activate = FB_ACTIVATE_TEST;
+ if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) {
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Checked mode %dx%d at %d bpp, got mode %dx%d at %d bpp\n", *w, *h, (index+1)*8, vinfo->xres, vinfo->yres, vinfo->bits_per_pixel);
+#endif
+ if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) {
+ *w = vinfo->xres;
+ *h = vinfo->yres;
+ mode_okay = 1;
+ }
+ }
+ return mode_okay;
+}
+
+static int FB_AddMode(_THIS, int index, unsigned int w, unsigned int h, int check_timings)
+{
+ SDL_Rect *mode;
+ int i;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( SDL_nummodes[index] > 0 ) {
+ mode = SDL_modelist[index][SDL_nummodes[index]-1];
+ if ( (mode->w == w) && (mode->h == h) ) {
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1);
+#endif
+ return(0);
+ }
+ }
+
+ /* Only allow a mode if we have a valid timing for it */
+ if ( check_timings ) {
+ int found_timing = 0;
+ for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) {
+ if ( (w == vesa_timings[i].xres) &&
+ (h == vesa_timings[i].yres) && vesa_timings[i].pixclock ) {
+ found_timing = 1;
+ break;
+ }
+ }
+ if ( !found_timing ) {
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "No valid timing line for mode %dx%d\n", w, h);
+#endif
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1);
+#endif
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ const SDL_Rect *a = *(const SDL_Rect**)va;
+ const SDL_Rect *b = *(const SDL_Rect**)vb;
+ if ( a->h == b->h )
+ return b->w - a->w;
+ else
+ return b->h - a->h;
+}
+
+static void FB_SortModes(_THIS)
+{
+ int i;
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_nummodes[i] > 0 ) {
+ SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
+ }
+ }
+}
+
+static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ const int pagesize = SDL_getpagesize();
+ struct fb_fix_screeninfo finfo;
+ struct fb_var_screeninfo vinfo;
+ int i, j;
+ int current_index;
+ unsigned int current_w;
+ unsigned int current_h;
+ const char *SDL_fbdev;
+ const char *rotation;
+ FILE *modesdb;
+
+ /* Initialize the library */
+ SDL_fbdev = SDL_getenv("SDL_FBDEV");
+ if ( SDL_fbdev == NULL ) {
+ SDL_fbdev = "/dev/fb0";
+ }
+ console_fd = open(SDL_fbdev, O_RDWR, 0);
+ if ( console_fd < 0 ) {
+ SDL_SetError("Unable to open %s", SDL_fbdev);
+ return(-1);
+ }
+
+#if !SDL_THREADS_DISABLED
+ /* Create the hardware surface lock mutex */
+ hw_lock = SDL_CreateMutex();
+ if ( hw_lock == NULL ) {
+ SDL_SetError("Unable to create lock mutex");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+#endif
+
+ /* Get the type of video hardware */
+ if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
+ SDL_SetError("Couldn't get console hardware info");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ switch (finfo.type) {
+ case FB_TYPE_PACKED_PIXELS:
+ /* Supported, no worries.. */
+ break;
+#ifdef VGA16_FBCON_SUPPORT
+ case FB_TYPE_VGA_PLANES:
+ /* VGA16 is supported, but that's it */
+ if ( finfo.type_aux == FB_AUX_VGA_PLANES_VGA4 ) {
+ if ( ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1) < 0 ) {
+ SDL_SetError("No I/O port permissions");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ this->SetVideoMode = FB_SetVGA16Mode;
+ break;
+ }
+ /* Fall through to unsupported case */
+#endif /* VGA16_FBCON_SUPPORT */
+ default:
+ SDL_SetError("Unsupported console hardware");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ switch (finfo.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_DIRECTCOLOR:
+ break;
+ default:
+ SDL_SetError("Unsupported console hardware");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+
+ /* Check if the user wants to disable hardware acceleration */
+ { const char *fb_accel;
+ fb_accel = SDL_getenv("SDL_FBACCEL");
+ if ( fb_accel ) {
+ finfo.accel = SDL_atoi(fb_accel);
+ }
+ }
+
+ /* Memory map the device, compensating for buggy PPC mmap() */
+ mapped_offset = (((long)finfo.smem_start) -
+ (((long)finfo.smem_start)&~(pagesize-1)));
+ mapped_memlen = finfo.smem_len+mapped_offset;
+ mapped_mem = do_mmap(NULL, mapped_memlen,
+ PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
+ if ( mapped_mem == (char *)-1 ) {
+ SDL_SetError("Unable to memory map the video hardware");
+ mapped_mem = NULL;
+ FB_VideoQuit(this);
+ return(-1);
+ }
+
+ /* Determine the current screen depth */
+ if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't get console pixel format");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ vformat->BitsPerPixel = vinfo.bits_per_pixel;
+ if ( vformat->BitsPerPixel < 8 ) {
+ /* Assuming VGA16, we handle this via a shadow framebuffer */
+ vformat->BitsPerPixel = 8;
+ }
+ for ( i=0; i<vinfo.red.length; ++i ) {
+ vformat->Rmask <<= 1;
+ vformat->Rmask |= (0x00000001<<vinfo.red.offset);
+ }
+ for ( i=0; i<vinfo.green.length; ++i ) {
+ vformat->Gmask <<= 1;
+ vformat->Gmask |= (0x00000001<<vinfo.green.offset);
+ }
+ for ( i=0; i<vinfo.blue.length; ++i ) {
+ vformat->Bmask <<= 1;
+ vformat->Bmask |= (0x00000001<<vinfo.blue.offset);
+ }
+ saved_vinfo = vinfo;
+
+ /* Save hardware palette, if needed */
+ FB_SavePalette(this, &finfo, &vinfo);
+
+ /* If the I/O registers are available, memory map them so we
+ can take advantage of any supported hardware acceleration.
+ */
+ vinfo.accel_flags = 0; /* Temporarily reserve registers */
+ ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo);
+ if ( finfo.accel && finfo.mmio_len ) {
+ mapped_iolen = finfo.mmio_len;
+ mapped_io = do_mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE,
+ MAP_SHARED, console_fd, mapped_memlen);
+ if ( mapped_io == (char *)-1 ) {
+ /* Hmm, failed to memory map I/O registers */
+ mapped_io = NULL;
+ }
+ }
+
+ rotate = FBCON_ROTATE_NONE;
+ rotation = SDL_getenv("SDL_VIDEO_FBCON_ROTATION");
+ if (rotation != NULL) {
+ if (SDL_strlen(rotation) == 0) {
+ shadow_fb = 0;
+ rotate = FBCON_ROTATE_NONE;
+#ifdef FBCON_DEBUG
+ printf("Not rotating, no shadow\n");
+#endif
+ } else if (!SDL_strcmp(rotation, "NONE")) {
+ shadow_fb = 1;
+ rotate = FBCON_ROTATE_NONE;
+#ifdef FBCON_DEBUG
+ printf("Not rotating, but still using shadow\n");
+#endif
+ } else if (!SDL_strcmp(rotation, "CW")) {
+ shadow_fb = 1;
+ rotate = FBCON_ROTATE_CW;
+#ifdef FBCON_DEBUG
+ printf("Rotating screen clockwise\n");
+#endif
+ } else if (!SDL_strcmp(rotation, "CCW")) {
+ shadow_fb = 1;
+ rotate = FBCON_ROTATE_CCW;
+#ifdef FBCON_DEBUG
+ printf("Rotating screen counter clockwise\n");
+#endif
+ } else if (!SDL_strcmp(rotation, "UD")) {
+ shadow_fb = 1;
+ rotate = FBCON_ROTATE_UD;
+#ifdef FBCON_DEBUG
+ printf("Rotating screen upside down\n");
+#endif
+ } else {
+ SDL_SetError("\"%s\" is not a valid value for "
+ "SDL_VIDEO_FBCON_ROTATION", rotation);
+ return(-1);
+ }
+ }
+
+ if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) {
+ current_w = vinfo.yres;
+ current_h = vinfo.xres;
+ } else {
+ current_w = vinfo.xres;
+ current_h = vinfo.yres;
+ }
+
+ /* Query for the list of available video modes */
+ current_index = ((vinfo.bits_per_pixel+7)/8)-1;
+ modesdb = fopen(FB_MODES_DB, "r");
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_nummodes[i] = 0;
+ SDL_modelist[i] = NULL;
+ }
+ if ( SDL_getenv("SDL_FB_BROKEN_MODES") != NULL ) {
+ FB_AddMode(this, current_index, current_w, current_h, 0);
+ } else if(modesdb) {
+ while ( read_fbmodes_mode(modesdb, &vinfo) ) {
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ unsigned int w, h;
+
+ if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) {
+ w = vinfo.yres;
+ h = vinfo.xres;
+ } else {
+ w = vinfo.xres;
+ h = vinfo.yres;
+ }
+ /* See if we are querying for the current mode */
+ if ( i == current_index ) {
+ if ( (current_w > w) || (current_h > h) ) {
+ /* Only check once */
+ FB_AddMode(this, i, current_w, current_h, 0);
+ current_index = -1;
+ }
+ }
+ if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) {
+ FB_AddMode(this, i, w, h, 0);
+ }
+ }
+ }
+ fclose(modesdb);
+ FB_SortModes(this);
+ } else {
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) {
+ unsigned int w, h;
+
+ if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) {
+ w = checkres[j].h;
+ h = checkres[j].w;
+ } else {
+ w = checkres[j].w;
+ h = checkres[j].h;
+ }
+ /* See if we are querying for the current mode */
+ if ( i == current_index ) {
+ if ( (current_w > w) || (current_h > h) ) {
+ /* Only check once */
+ FB_AddMode(this, i, current_w, current_h, 0);
+ current_index = -1;
+ }
+ }
+ if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) {
+ FB_AddMode(this, i, w, h, 1);
+ }
+ }
+ }
+ }
+
+ this->info.current_w = current_w;
+ this->info.current_h = current_h;
+ this->info.wm_available = 0;
+ this->info.hw_available = !shadow_fb;
+ this->info.video_mem = shadow_fb ? 0 : finfo.smem_len/1024;
+ /* Fill in our hardware acceleration capabilities */
+ if ( mapped_io ) {
+ switch (finfo.accel) {
+ case FB_ACCEL_MATROX_MGA2064W:
+ case FB_ACCEL_MATROX_MGA1064SG:
+ case FB_ACCEL_MATROX_MGA2164W:
+ case FB_ACCEL_MATROX_MGA2164W_AGP:
+ case FB_ACCEL_MATROX_MGAG100:
+ /*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */
+ case FB_ACCEL_MATROX_MGAG400:
+#ifdef FBACCEL_DEBUG
+ printf("Matrox hardware accelerator!\n");
+#endif
+ FB_MatroxAccel(this, finfo.accel);
+ break;
+ case FB_ACCEL_3DFX_BANSHEE:
+#ifdef FBACCEL_DEBUG
+ printf("3DFX hardware accelerator!\n");
+#endif
+ FB_3DfxAccel(this, finfo.accel);
+ break;
+ case FB_ACCEL_NV3:
+ case FB_ACCEL_NV4:
+#ifdef FBACCEL_DEBUG
+ printf("NVidia hardware accelerator!\n");
+#endif
+ FB_RivaAccel(this, finfo.accel);
+ break;
+ default:
+#ifdef FBACCEL_DEBUG
+ printf("Unknown hardware accelerator.\n");
+#endif
+ break;
+ }
+ }
+
+ if (shadow_fb) {
+ shadow_mem = (char *)SDL_malloc(mapped_memlen);
+ if (shadow_mem == NULL) {
+ SDL_SetError("No memory for shadow");
+ return (-1);
+ }
+ }
+
+ /* Enable mouse and keyboard support */
+ if ( FB_OpenKeyboard(this) < 0 ) {
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ if ( FB_OpenMouse(this) < 0 ) {
+ const char *sdl_nomouse;
+
+ sdl_nomouse = SDL_getenv("SDL_NOMOUSE");
+ if ( ! sdl_nomouse ) {
+ SDL_SetError("Unable to open mouse");
+ FB_VideoQuit(this);
+ return(-1);
+ }
+ }
+
+ /* We're done! */
+ return(0);
+}
+
+static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+}
+
+/* Various screen update functions available */
+static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+#ifdef VGA16_FBCON_SUPPORT
+static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects);
+#endif
+
+#ifdef FBCON_DEBUG
+static void print_vinfo(struct fb_var_screeninfo *vinfo)
+{
+ fprintf(stderr, "Printing vinfo:\n");
+ fprintf(stderr, "\txres: %d\n", vinfo->xres);
+ fprintf(stderr, "\tyres: %d\n", vinfo->yres);
+ fprintf(stderr, "\txres_virtual: %d\n", vinfo->xres_virtual);
+ fprintf(stderr, "\tyres_virtual: %d\n", vinfo->yres_virtual);
+ fprintf(stderr, "\txoffset: %d\n", vinfo->xoffset);
+ fprintf(stderr, "\tyoffset: %d\n", vinfo->yoffset);
+ fprintf(stderr, "\tbits_per_pixel: %d\n", vinfo->bits_per_pixel);
+ fprintf(stderr, "\tgrayscale: %d\n", vinfo->grayscale);
+ fprintf(stderr, "\tnonstd: %d\n", vinfo->nonstd);
+ fprintf(stderr, "\tactivate: %d\n", vinfo->activate);
+ fprintf(stderr, "\theight: %d\n", vinfo->height);
+ fprintf(stderr, "\twidth: %d\n", vinfo->width);
+ fprintf(stderr, "\taccel_flags: %d\n", vinfo->accel_flags);
+ fprintf(stderr, "\tpixclock: %d\n", vinfo->pixclock);
+ fprintf(stderr, "\tleft_margin: %d\n", vinfo->left_margin);
+ fprintf(stderr, "\tright_margin: %d\n", vinfo->right_margin);
+ fprintf(stderr, "\tupper_margin: %d\n", vinfo->upper_margin);
+ fprintf(stderr, "\tlower_margin: %d\n", vinfo->lower_margin);
+ fprintf(stderr, "\thsync_len: %d\n", vinfo->hsync_len);
+ fprintf(stderr, "\tvsync_len: %d\n", vinfo->vsync_len);
+ fprintf(stderr, "\tsync: %d\n", vinfo->sync);
+ fprintf(stderr, "\tvmode: %d\n", vinfo->vmode);
+ fprintf(stderr, "\tred: %d/%d\n", vinfo->red.length, vinfo->red.offset);
+ fprintf(stderr, "\tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset);
+ fprintf(stderr, "\tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset);
+ fprintf(stderr, "\talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset);
+}
+static void print_finfo(struct fb_fix_screeninfo *finfo)
+{
+ fprintf(stderr, "Printing finfo:\n");
+ fprintf(stderr, "\tsmem_start = %p\n", (char *)finfo->smem_start);
+ fprintf(stderr, "\tsmem_len = %d\n", finfo->smem_len);
+ fprintf(stderr, "\ttype = %d\n", finfo->type);
+ fprintf(stderr, "\ttype_aux = %d\n", finfo->type_aux);
+ fprintf(stderr, "\tvisual = %d\n", finfo->visual);
+ fprintf(stderr, "\txpanstep = %d\n", finfo->xpanstep);
+ fprintf(stderr, "\typanstep = %d\n", finfo->ypanstep);
+ fprintf(stderr, "\tywrapstep = %d\n", finfo->ywrapstep);
+ fprintf(stderr, "\tline_length = %d\n", finfo->line_length);
+ fprintf(stderr, "\tmmio_start = %p\n", (char *)finfo->mmio_start);
+ fprintf(stderr, "\tmmio_len = %d\n", finfo->mmio_len);
+ fprintf(stderr, "\taccel = %d\n", finfo->accel);
+}
+#endif
+
+static int choose_fbmodes_mode(struct fb_var_screeninfo *vinfo)
+{
+ int matched;
+ FILE *modesdb;
+ struct fb_var_screeninfo cinfo;
+
+ matched = 0;
+ modesdb = fopen(FB_MODES_DB, "r");
+ if ( modesdb ) {
+ /* Parse the mode definition file */
+ while ( read_fbmodes_mode(modesdb, &cinfo) ) {
+ if ( (vinfo->xres == cinfo.xres && vinfo->yres == cinfo.yres) &&
+ (!matched || (vinfo->bits_per_pixel == cinfo.bits_per_pixel)) ) {
+ vinfo->pixclock = cinfo.pixclock;
+ vinfo->left_margin = cinfo.left_margin;
+ vinfo->right_margin = cinfo.right_margin;
+ vinfo->upper_margin = cinfo.upper_margin;
+ vinfo->lower_margin = cinfo.lower_margin;
+ vinfo->hsync_len = cinfo.hsync_len;
+ vinfo->vsync_len = cinfo.vsync_len;
+ if ( matched ) {
+ break;
+ }
+ matched = 1;
+ }
+ }
+ fclose(modesdb);
+ }
+ return(matched);
+}
+
+static int choose_vesa_mode(struct fb_var_screeninfo *vinfo)
+{
+ int matched;
+ int i;
+
+ /* Check for VESA timings */
+ matched = 0;
+ for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) {
+ if ( (vinfo->xres == vesa_timings[i].xres) &&
+ (vinfo->yres == vesa_timings[i].yres) ) {
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Using VESA timings for %dx%d\n",
+ vinfo->xres, vinfo->yres);
+#endif
+ if ( vesa_timings[i].pixclock ) {
+ vinfo->pixclock = vesa_timings[i].pixclock;
+ }
+ vinfo->left_margin = vesa_timings[i].left;
+ vinfo->right_margin = vesa_timings[i].right;
+ vinfo->upper_margin = vesa_timings[i].upper;
+ vinfo->lower_margin = vesa_timings[i].lower;
+ vinfo->hsync_len = vesa_timings[i].hslen;
+ vinfo->vsync_len = vesa_timings[i].vslen;
+ vinfo->sync = vesa_timings[i].sync;
+ vinfo->vmode = vesa_timings[i].vmode;
+ matched = 1;
+ break;
+ }
+ }
+ return(matched);
+}
+
+#ifdef VGA16_FBCON_SUPPORT
+static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ struct fb_fix_screeninfo finfo;
+ struct fb_var_screeninfo vinfo;
+
+ /* Set the terminal into graphics mode */
+ if ( FB_EnterGraphicsMode(this) < 0 ) {
+ return(NULL);
+ }
+
+ /* Restore the original palette */
+ FB_RestorePalette(this);
+
+ /* Set the video mode and get the final screen format */
+ if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't get console screen info");
+ return(NULL);
+ }
+ cache_vinfo = vinfo;
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Printing actual vinfo:\n");
+ print_vinfo(&vinfo);
+#endif
+ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
+ return(NULL);
+ }
+ current->format->palette->ncolors = 16;
+
+ /* Get the fixed information about the console hardware.
+ This is necessary since finfo.line_length changes.
+ */
+ if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
+ SDL_SetError("Couldn't get console hardware info");
+ return(NULL);
+ }
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Printing actual finfo:\n");
+ print_finfo(&finfo);
+#endif
+
+ /* Save hardware palette, if needed */
+ FB_SavePalette(this, &finfo, &vinfo);
+
+ /* Set up the new mode framebuffer */
+ current->flags = SDL_FULLSCREEN;
+ current->w = vinfo.xres;
+ current->h = vinfo.yres;
+ current->pitch = current->w;
+ current->pixels = SDL_malloc(current->h*current->pitch);
+
+ /* Set the update rectangle function */
+ this->UpdateRects = FB_VGA16Update;
+
+ /* We're done */
+ return(current);
+}
+#endif /* VGA16_FBCON_SUPPORT */
+
+static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ struct fb_fix_screeninfo finfo;
+ struct fb_var_screeninfo vinfo;
+ int i;
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ char *surfaces_mem;
+ int surfaces_len;
+
+ /* Set the terminal into graphics mode */
+ if ( FB_EnterGraphicsMode(this) < 0 ) {
+ return(NULL);
+ }
+
+ /* Restore the original palette */
+ FB_RestorePalette(this);
+
+ /* Set the video mode and get the final screen format */
+ if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't get console screen info");
+ return(NULL);
+ }
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Printing original vinfo:\n");
+ print_vinfo(&vinfo);
+#endif
+ /* Do not use double buffering with shadow buffer */
+ if (shadow_fb) {
+ flags &= ~SDL_DOUBLEBUF;
+ }
+
+ if ( (vinfo.xres != width) || (vinfo.yres != height) ||
+ (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) {
+ vinfo.activate = FB_ACTIVATE_NOW;
+ vinfo.accel_flags = 0;
+ vinfo.bits_per_pixel = bpp;
+ vinfo.xres = width;
+ vinfo.xres_virtual = width;
+ vinfo.yres = height;
+ if ( flags & SDL_DOUBLEBUF ) {
+ vinfo.yres_virtual = height*2;
+ } else {
+ vinfo.yres_virtual = height;
+ }
+ vinfo.xoffset = 0;
+ vinfo.yoffset = 0;
+ vinfo.red.length = vinfo.red.offset = 0;
+ vinfo.green.length = vinfo.green.offset = 0;
+ vinfo.blue.length = vinfo.blue.offset = 0;
+ vinfo.transp.length = vinfo.transp.offset = 0;
+ if ( ! choose_fbmodes_mode(&vinfo) ) {
+ choose_vesa_mode(&vinfo);
+ }
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Printing wanted vinfo:\n");
+ print_vinfo(&vinfo);
+#endif
+ if ( !shadow_fb &&
+ ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
+ vinfo.yres_virtual = height;
+ if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't set console screen info");
+ return(NULL);
+ }
+ }
+ } else {
+ int maxheight;
+
+ /* Figure out how much video memory is available */
+ if ( flags & SDL_DOUBLEBUF ) {
+ maxheight = height*2;
+ } else {
+ maxheight = height;
+ }
+ if ( vinfo.yres_virtual > maxheight ) {
+ vinfo.yres_virtual = maxheight;
+ }
+ }
+ cache_vinfo = vinfo;
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Printing actual vinfo:\n");
+ print_vinfo(&vinfo);
+#endif
+ Rmask = 0;
+ for ( i=0; i<vinfo.red.length; ++i ) {
+ Rmask <<= 1;
+ Rmask |= (0x00000001<<vinfo.red.offset);
+ }
+ Gmask = 0;
+ for ( i=0; i<vinfo.green.length; ++i ) {
+ Gmask <<= 1;
+ Gmask |= (0x00000001<<vinfo.green.offset);
+ }
+ Bmask = 0;
+ for ( i=0; i<vinfo.blue.length; ++i ) {
+ Bmask <<= 1;
+ Bmask |= (0x00000001<<vinfo.blue.offset);
+ }
+ if ( ! SDL_ReallocFormat(current, vinfo.bits_per_pixel,
+ Rmask, Gmask, Bmask, 0) ) {
+ return(NULL);
+ }
+
+ /* Get the fixed information about the console hardware.
+ This is necessary since finfo.line_length changes.
+ */
+ if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
+ SDL_SetError("Couldn't get console hardware info");
+ return(NULL);
+ }
+
+ /* Save hardware palette, if needed */
+ FB_SavePalette(this, &finfo, &vinfo);
+
+ if (shadow_fb) {
+ if (vinfo.bits_per_pixel == 16) {
+ blitFunc = (rotate == FBCON_ROTATE_NONE ||
+ rotate == FBCON_ROTATE_UD) ?
+ FB_blit16 : FB_blit16blocked;
+ } else {
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Init vinfo:\n");
+ print_vinfo(&vinfo);
+#endif
+ SDL_SetError("Using software buffer, but no blitter "
+ "function is available for %d bpp.",
+ vinfo.bits_per_pixel);
+ return(NULL);
+ }
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags &= SDL_FULLSCREEN;
+ if (shadow_fb) {
+ current->flags |= SDL_SWSURFACE;
+ } else {
+ current->flags |= SDL_HWSURFACE;
+ }
+ current->w = vinfo.xres;
+ current->h = vinfo.yres;
+ if (shadow_fb) {
+ current->pitch = current->w * ((vinfo.bits_per_pixel + 7) / 8);
+ current->pixels = shadow_mem;
+ physlinebytes = finfo.line_length;
+ } else {
+ current->pitch = finfo.line_length;
+ current->pixels = mapped_mem+mapped_offset;
+ }
+
+ /* Set up the information for hardware surfaces */
+ surfaces_mem = (char *)current->pixels +
+ vinfo.yres_virtual*current->pitch;
+ surfaces_len = (shadow_fb) ?
+ 0 : (mapped_memlen-(surfaces_mem-mapped_mem));
+
+ FB_FreeHWSurfaces(this);
+ FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
+
+ /* Let the application know we have a hardware palette */
+ switch (finfo.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ current->flags |= SDL_HWPALETTE;
+ break;
+ default:
+ break;
+ }
+
+ /* Update for double-buffering, if we can */
+ if ( flags & SDL_DOUBLEBUF ) {
+ if ( vinfo.yres_virtual == (height*2) ) {
+ current->flags |= SDL_DOUBLEBUF;
+ flip_page = 0;
+ flip_address[0] = (char *)current->pixels;
+ flip_address[1] = (char *)current->pixels+
+ current->h*current->pitch;
+ this->screen = current;
+ FB_FlipHWSurface(this, current);
+ this->screen = NULL;
+ }
+ }
+
+ /* Set the update rectangle function */
+ this->UpdateRects = FB_DirectUpdate;
+
+ /* We're done */
+ return(current);
+}
+
+#ifdef FBCON_DEBUG
+void FB_DumpHWSurfaces(_THIS)
+{
+ vidmem_bucket *bucket;
+
+ printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal);
+ printf("\n");
+ printf(" Base Size\n");
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free");
+ if ( bucket->prev ) {
+ if ( bucket->base != bucket->prev->base+bucket->prev->size ) {
+ printf("Warning, corrupt bucket list! (prev)\n");
+ }
+ } else {
+ if ( bucket != &surfaces ) {
+ printf("Warning, corrupt bucket list! (!prev)\n");
+ }
+ }
+ if ( bucket->next ) {
+ if ( bucket->next->base != bucket->base+bucket->size ) {
+ printf("Warning, corrupt bucket list! (next)\n");
+ }
+ }
+ }
+ printf("\n");
+}
+#endif
+
+static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size)
+{
+ vidmem_bucket *bucket;
+
+ surfaces_memtotal = size;
+ surfaces_memleft = size;
+
+ if ( surfaces_memleft > 0 ) {
+ bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket));
+ if ( bucket == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ bucket->prev = &surfaces;
+ bucket->used = 0;
+ bucket->dirty = 0;
+ bucket->base = base;
+ bucket->size = size;
+ bucket->next = NULL;
+ } else {
+ bucket = NULL;
+ }
+
+ surfaces.prev = NULL;
+ surfaces.used = 1;
+ surfaces.dirty = 0;
+ surfaces.base = screen->pixels;
+ surfaces.size = (unsigned int)((long)base - (long)surfaces.base);
+ surfaces.next = bucket;
+ screen->hwdata = (struct private_hwdata *)&surfaces;
+ return(0);
+}
+static void FB_FreeHWSurfaces(_THIS)
+{
+ vidmem_bucket *bucket, *freeable;
+
+ bucket = surfaces.next;
+ while ( bucket ) {
+ freeable = bucket;
+ bucket = bucket->next;
+ SDL_free(freeable);
+ }
+ surfaces.next = NULL;
+}
+
+static int FB_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ vidmem_bucket *bucket;
+ int size;
+ int extra;
+
+/* Temporarily, we only allow surfaces the same width as display.
+ Some blitters require the pitch between two hardware surfaces
+ to be the same. Others have interesting alignment restrictions.
+ Until someone who knows these details looks at the code...
+*/
+if ( surface->pitch > SDL_VideoSurface->pitch ) {
+ SDL_SetError("Surface requested wider than screen");
+ return(-1);
+}
+surface->pitch = SDL_VideoSurface->pitch;
+ size = surface->h * surface->pitch;
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Allocating bucket of %d bytes\n", size);
+#endif
+
+ /* Quick check for available mem */
+ if ( size > surfaces_memleft ) {
+ SDL_SetError("Not enough video memory");
+ return(-1);
+ }
+
+ /* Search for an empty bucket big enough */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ if ( ! bucket->used && (size <= bucket->size) ) {
+ break;
+ }
+ }
+ if ( bucket == NULL ) {
+ SDL_SetError("Video memory too fragmented");
+ return(-1);
+ }
+
+ /* Create a new bucket for left-over memory */
+ extra = (bucket->size - size);
+ if ( extra ) {
+ vidmem_bucket *newbucket;
+
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Adding new free bucket of %d bytes\n", extra);
+#endif
+ newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket));
+ if ( newbucket == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ newbucket->prev = bucket;
+ newbucket->used = 0;
+ newbucket->base = bucket->base+size;
+ newbucket->size = extra;
+ newbucket->next = bucket->next;
+ if ( bucket->next ) {
+ bucket->next->prev = newbucket;
+ }
+ bucket->next = newbucket;
+ }
+
+ /* Set the current bucket values and return it! */
+ bucket->used = 1;
+ bucket->size = size;
+ bucket->dirty = 0;
+#ifdef FBCON_DEBUG
+ fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);
+#endif
+ surfaces_memleft -= size;
+ surface->flags |= SDL_HWSURFACE;
+ surface->pixels = bucket->base;
+ surface->hwdata = (struct private_hwdata *)bucket;
+ return(0);
+}
+static void FB_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ vidmem_bucket *bucket, *freeable;
+
+ /* Look for the bucket in the current list */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ if ( bucket == (vidmem_bucket *)surface->hwdata ) {
+ break;
+ }
+ }
+ if ( bucket && bucket->used ) {
+ /* Add the memory back to the total */
+#ifdef DGA_DEBUG
+ printf("Freeing bucket of %d bytes\n", bucket->size);
+#endif
+ surfaces_memleft += bucket->size;
+
+ /* Can we merge the space with surrounding buckets? */
+ bucket->used = 0;
+ if ( bucket->next && ! bucket->next->used ) {
+#ifdef DGA_DEBUG
+ printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);
+#endif
+ freeable = bucket->next;
+ bucket->size += bucket->next->size;
+ bucket->next = bucket->next->next;
+ if ( bucket->next ) {
+ bucket->next->prev = bucket;
+ }
+ SDL_free(freeable);
+ }
+ if ( bucket->prev && ! bucket->prev->used ) {
+#ifdef DGA_DEBUG
+ printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);
+#endif
+ freeable = bucket;
+ bucket->prev->size += bucket->size;
+ bucket->prev->next = bucket->next;
+ if ( bucket->next ) {
+ bucket->next->prev = bucket->prev;
+ }
+ SDL_free(freeable);
+ }
+ }
+ surface->pixels = NULL;
+ surface->hwdata = NULL;
+}
+
+static int FB_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+ if ( surface == this->screen ) {
+ SDL_mutexP(hw_lock);
+ if ( FB_IsSurfaceBusy(surface) ) {
+ FB_WaitBusySurfaces(this);
+ }
+ } else {
+ if ( FB_IsSurfaceBusy(surface) ) {
+ FB_WaitBusySurfaces(this);
+ }
+ }
+ return(0);
+}
+static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface == this->screen ) {
+ SDL_mutexV(hw_lock);
+ }
+}
+
+static void FB_WaitVBL(_THIS)
+{
+#ifdef FBIOWAITRETRACE /* Heheh, this didn't make it into the main kernel */
+ ioctl(console_fd, FBIOWAITRETRACE, 0);
+#endif
+ return;
+}
+
+static void FB_WaitIdle(_THIS)
+{
+ return;
+}
+
+static int FB_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( switched_away ) {
+ return -2; /* no hardware access */
+ }
+
+ /* Wait for vertical retrace and then flip display */
+ cache_vinfo.yoffset = flip_page*surface->h;
+ if ( FB_IsSurfaceBusy(this->screen) ) {
+ FB_WaitBusySurfaces(this);
+ }
+ wait_vbl(this);
+ if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) {
+ SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed");
+ return(-1);
+ }
+ flip_page = !flip_page;
+
+ surface->pixels = flip_address[flip_page];
+ return(0);
+}
+
+static void FB_blit16(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta,
+ Uint8 *byte_dst_pos, int dst_linebytes, int width, int height)
+{
+ int w;
+ Uint16 *src_pos = (Uint16 *)byte_src_pos;
+ Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
+
+ while (height) {
+ Uint16 *src = src_pos;
+ Uint16 *dst = dst_pos;
+ for (w = width; w != 0; w--) {
+ *dst = *src;
+ src += src_right_delta;
+ dst++;
+ }
+ dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes);
+ src_pos += src_down_delta;
+ height--;
+ }
+}
+
+#define BLOCKSIZE_W 32
+#define BLOCKSIZE_H 32
+
+static void FB_blit16blocked(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta,
+ Uint8 *byte_dst_pos, int dst_linebytes, int width, int height)
+{
+ int w;
+ Uint16 *src_pos = (Uint16 *)byte_src_pos;
+ Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
+
+ while (height > 0) {
+ Uint16 *src = src_pos;
+ Uint16 *dst = dst_pos;
+ for (w = width; w > 0; w -= BLOCKSIZE_W) {
+ FB_blit16((Uint8 *)src,
+ src_right_delta,
+ src_down_delta,
+ (Uint8 *)dst,
+ dst_linebytes,
+ min(w, BLOCKSIZE_W),
+ min(height, BLOCKSIZE_H));
+ src += src_right_delta * BLOCKSIZE_W;
+ dst += BLOCKSIZE_W;
+ }
+ dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H);
+ src_pos += src_down_delta * BLOCKSIZE_H;
+ height -= BLOCKSIZE_H;
+ }
+}
+
+static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int width = cache_vinfo.xres;
+ int height = cache_vinfo.yres;
+ int bytes_per_pixel = (cache_vinfo.bits_per_pixel + 7) / 8;
+ int i;
+
+ if (!shadow_fb) {
+ /* The application is already updating the visible video memory */
+ return;
+ }
+
+ if (cache_vinfo.bits_per_pixel != 16) {
+ SDL_SetError("Shadow copy only implemented for 16 bpp");
+ return;
+ }
+
+ for (i = 0; i < numrects; i++) {
+ int x1, y1, x2, y2;
+ int scr_x1, scr_y1, scr_x2, scr_y2;
+ int sha_x1, sha_y1;
+ int shadow_right_delta; /* Address change when moving right in dest */
+ int shadow_down_delta; /* Address change when moving down in dest */
+ char *src_start;
+ char *dst_start;
+
+ x1 = rects[i].x;
+ y1 = rects[i].y;
+ x2 = x1 + rects[i].w;
+ y2 = y1 + rects[i].h;
+
+ if (x1 < 0) {
+ x1 = 0;
+ } else if (x1 > width) {
+ x1 = width;
+ }
+ if (x2 < 0) {
+ x2 = 0;
+ } else if (x2 > width) {
+ x2 = width;
+ }
+ if (y1 < 0) {
+ y1 = 0;
+ } else if (y1 > height) {
+ y1 = height;
+ }
+ if (y2 < 0) {
+ y2 = 0;
+ } else if (y2 > height) {
+ y2 = height;
+ }
+ if (x2 <= x1 || y2 <= y1) {
+ continue;
+ }
+
+ switch (rotate) {
+ case FBCON_ROTATE_NONE:
+ sha_x1 = scr_x1 = x1;
+ sha_y1 = scr_y1 = y1;
+ scr_x2 = x2;
+ scr_y2 = y2;
+ shadow_right_delta = 1;
+ shadow_down_delta = width;
+ break;
+ case FBCON_ROTATE_CCW:
+ scr_x1 = y1;
+ scr_y1 = width - x2;
+ scr_x2 = y2;
+ scr_y2 = width - x1;
+ sha_x1 = x2 - 1;
+ sha_y1 = y1;
+ shadow_right_delta = width;
+ shadow_down_delta = -1;
+ break;
+ case FBCON_ROTATE_UD:
+ scr_x1 = width - x2;
+ scr_y1 = height - y2;
+ scr_x2 = width - x1;
+ scr_y2 = height - y1;
+ sha_x1 = x2 - 1;
+ sha_y1 = y2 - 1;
+ shadow_right_delta = -1;
+ shadow_down_delta = -width;
+ break;
+ case FBCON_ROTATE_CW:
+ scr_x1 = height - y2;
+ scr_y1 = x1;
+ scr_x2 = height - y1;
+ scr_y2 = x2;
+ sha_x1 = x1;
+ sha_y1 = y2 - 1;
+ shadow_right_delta = -width;
+ shadow_down_delta = 1;
+ break;
+ default:
+ SDL_SetError("Unknown rotation");
+ return;
+ }
+
+ src_start = shadow_mem +
+ (sha_y1 * width + sha_x1) * bytes_per_pixel;
+ dst_start = mapped_mem + mapped_offset + scr_y1 * physlinebytes +
+ scr_x1 * bytes_per_pixel;
+
+ blitFunc((Uint8 *) src_start,
+ shadow_right_delta,
+ shadow_down_delta,
+ (Uint8 *) dst_start,
+ physlinebytes,
+ scr_x2 - scr_x1,
+ scr_y2 - scr_y1);
+ }
+}
+
+#ifdef VGA16_FBCON_SUPPORT
+/* Code adapted with thanks from the XFree86 VGA16 driver! :) */
+#define writeGr(index, value) \
+outb(index, 0x3CE); \
+outb(value, 0x3CF);
+#define writeSeq(index, value) \
+outb(index, 0x3C4); \
+outb(value, 0x3C5);
+
+static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects)
+{
+ SDL_Surface *screen;
+ int width, height, FBPitch, left, i, j, SRCPitch, phase;
+ register Uint32 m;
+ Uint8 s1, s2, s3, s4;
+ Uint32 *src, *srcPtr;
+ Uint8 *dst, *dstPtr;
+
+ if ( switched_away ) {
+ return; /* no hardware access */
+ }
+
+ screen = this->screen;
+ FBPitch = screen->w >> 3;
+ SRCPitch = screen->pitch >> 2;
+
+ writeGr(0x03, 0x00);
+ writeGr(0x05, 0x00);
+ writeGr(0x01, 0x00);
+ writeGr(0x08, 0xFF);
+
+ while(numrects--) {
+ left = rects->x & ~7;
+ width = (rects->w + 7) >> 3;
+ height = rects->h;
+ src = (Uint32*)screen->pixels + (rects->y * SRCPitch) + (left >> 2);
+ dst = (Uint8*)mapped_mem + (rects->y * FBPitch) + (left >> 3);
+
+ if((phase = (long)dst & 3L)) {
+ phase = 4 - phase;
+ if(phase > width) phase = width;
+ width -= phase;
+ }
+
+ while(height--) {
+ writeSeq(0x02, 1 << 0);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4);
+ s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4);
+ s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4);
+ s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ srcPtr += 2;
+ }
+
+ writeSeq(0x02, 1 << 1);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4);
+ s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4);
+ s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4);
+ s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ srcPtr += 2;
+ }
+
+ writeSeq(0x02, 1 << 2);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4);
+ s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4);
+ s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4);
+ s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ srcPtr += 2;
+ }
+
+ writeSeq(0x02, 1 << 3);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ s1 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4);
+ s2 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4);
+ s3 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4);
+ s4 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ srcPtr += 2;
+ }
+
+ dst += FBPitch;
+ src += SRCPitch;
+ }
+ rects++;
+ }
+}
+#endif /* VGA16_FBCON_SUPPORT */
+
+void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area)
+{
+ struct fb_cmap cmap;
+
+ cmap.start = 0;
+ cmap.len = palette_len;
+ cmap.red = &area[0*palette_len];
+ cmap.green = &area[1*palette_len];
+ cmap.blue = &area[2*palette_len];
+ cmap.transp = NULL;
+ ioctl(console_fd, FBIOGETCMAP, &cmap);
+}
+
+void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area)
+{
+ struct fb_cmap cmap;
+
+ cmap.start = 0;
+ cmap.len = palette_len;
+ cmap.red = &area[0*palette_len];
+ cmap.green = &area[1*palette_len];
+ cmap.blue = &area[2*palette_len];
+ cmap.transp = NULL;
+ ioctl(console_fd, FBIOPUTCMAP, &cmap);
+}
+
+static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo,
+ struct fb_var_screeninfo *vinfo)
+{
+ int i;
+
+ /* Save hardware palette, if needed */
+ if ( finfo->visual == FB_VISUAL_PSEUDOCOLOR ) {
+ saved_cmaplen = 1<<vinfo->bits_per_pixel;
+ saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap));
+ if ( saved_cmap != NULL ) {
+ FB_SavePaletteTo(this, saved_cmaplen, saved_cmap);
+ }
+ }
+
+ /* Added support for FB_VISUAL_DIRECTCOLOR.
+ With this mode pixel information is passed through the palette...
+ Neat fading and gamma correction effects can be had by simply
+ fooling around with the palette instead of changing the pixel
+ values themselves... Very neat!
+
+ Adam Meyerowitz 1/19/2000
+ ameyerow@optonline.com
+ */
+ if ( finfo->visual == FB_VISUAL_DIRECTCOLOR ) {
+ __u16 new_entries[3*256];
+
+ /* Save the colormap */
+ saved_cmaplen = 256;
+ saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap));
+ if ( saved_cmap != NULL ) {
+ FB_SavePaletteTo(this, saved_cmaplen, saved_cmap);
+ }
+
+ /* Allocate new identity colormap */
+ for ( i=0; i<256; ++i ) {
+ new_entries[(0*256)+i] =
+ new_entries[(1*256)+i] =
+ new_entries[(2*256)+i] = (i<<8)|i;
+ }
+ FB_RestorePaletteFrom(this, 256, new_entries);
+ }
+}
+
+static void FB_RestorePalette(_THIS)
+{
+ /* Restore the original palette */
+ if ( saved_cmap ) {
+ FB_RestorePaletteFrom(this, saved_cmaplen, saved_cmap);
+ SDL_free(saved_cmap);
+ saved_cmap = NULL;
+ }
+}
+
+static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ __u16 r[256];
+ __u16 g[256];
+ __u16 b[256];
+ struct fb_cmap cmap;
+
+ /* Set up the colormap */
+ for (i = 0; i < ncolors; i++) {
+ r[i] = colors[i].r << 8;
+ g[i] = colors[i].g << 8;
+ b[i] = colors[i].b << 8;
+ }
+ cmap.start = firstcolor;
+ cmap.len = ncolors;
+ cmap.red = r;
+ cmap.green = g;
+ cmap.blue = b;
+ cmap.transp = NULL;
+
+ if( (ioctl(console_fd, FBIOPUTCMAP, &cmap) < 0) ||
+ !(this->screen->flags & SDL_HWPALETTE) ) {
+ colors = this->screen->format->palette->colors;
+ ncolors = this->screen->format->palette->ncolors;
+ cmap.start = 0;
+ cmap.len = ncolors;
+ SDL_memset(r, 0, sizeof(r));
+ SDL_memset(g, 0, sizeof(g));
+ SDL_memset(b, 0, sizeof(b));
+ if ( ioctl(console_fd, FBIOGETCMAP, &cmap) == 0 ) {
+ for ( i=ncolors-1; i>=0; --i ) {
+ colors[i].r = (r[i]>>8);
+ colors[i].g = (g[i]>>8);
+ colors[i].b = (b[i]>>8);
+ }
+ }
+ return(0);
+ }
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+static void FB_VideoQuit(_THIS)
+{
+ int i, j;
+
+ if ( this->screen ) {
+ /* Clear screen and tell SDL not to free the pixels */
+
+ const char *dontClearPixels = SDL_getenv("SDL_FBCON_DONT_CLEAR");
+
+ /* If the framebuffer is not to be cleared, make sure that we won't
+ * display the previous frame when disabling double buffering. */
+ if ( dontClearPixels && flip_page == 0 ) {
+ SDL_memcpy(flip_address[0], flip_address[1], this->screen->pitch * this->screen->h);
+ }
+
+ if ( !dontClearPixels && this->screen->pixels && FB_InGraphicsMode(this) ) {
+#if defined(__powerpc__) || defined(__ia64__) /* SIGBUS when using SDL_memset() ?? */
+ Uint8 *rowp = (Uint8 *)this->screen->pixels;
+ int left = this->screen->pitch*this->screen->h;
+ while ( left-- ) { *rowp++ = 0; }
+#else
+ SDL_memset(this->screen->pixels,0,this->screen->h*this->screen->pitch);
+#endif
+ }
+ /* This test fails when using the VGA16 shadow memory */
+ if ( ((char *)this->screen->pixels >= mapped_mem) &&
+ ((char *)this->screen->pixels < (mapped_mem+mapped_memlen)) ) {
+ this->screen->pixels = NULL;
+ }
+ }
+
+ /* Clear the lock mutex */
+ if ( hw_lock ) {
+ SDL_DestroyMutex(hw_lock);
+ hw_lock = NULL;
+ }
+
+ /* Clean up defined video modes */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ for ( j=0; SDL_modelist[i][j]; ++j ) {
+ SDL_free(SDL_modelist[i][j]);
+ }
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ /* Clean up the memory bucket list */
+ FB_FreeHWSurfaces(this);
+
+ /* Close console and input file descriptors */
+ if ( console_fd > 0 ) {
+ /* Unmap the video framebuffer and I/O registers */
+ if ( mapped_mem ) {
+ munmap(mapped_mem, mapped_memlen);
+ mapped_mem = NULL;
+ }
+ if ( mapped_io ) {
+ munmap(mapped_io, mapped_iolen);
+ mapped_io = NULL;
+ }
+
+ /* Restore the original video mode and palette */
+ if ( FB_InGraphicsMode(this) ) {
+ FB_RestorePalette(this);
+ ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo);
+ }
+
+ /* We're all done with the framebuffer */
+ close(console_fd);
+ console_fd = -1;
+ }
+ FB_CloseMouse(this);
+ FB_CloseKeyboard(this);
+}
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.h b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.h
new file mode 100644
index 0000000..1443d2b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/SDL_fbvideo.h
@@ -0,0 +1,200 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_fbvideo_h
+#define _SDL_fbvideo_h
+
+#include <sys/types.h>
+#include <termios.h>
+#include <linux/fb.h>
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+#if SDL_INPUT_TSLIB
+#include "tslib.h"
+#endif
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+typedef void FB_bitBlit(
+ Uint8 *src_pos,
+ int src_right_delta, /* pixels, not bytes */
+ int src_down_delta, /* pixels, not bytes */
+ Uint8 *dst_pos,
+ int dst_linebytes,
+ int width,
+ int height);
+
+/* This is the structure we use to keep track of video memory */
+typedef struct vidmem_bucket {
+ struct vidmem_bucket *prev;
+ int used;
+ int dirty;
+ char *base;
+ unsigned int size;
+ struct vidmem_bucket *next;
+} vidmem_bucket;
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ int console_fd;
+ struct fb_var_screeninfo cache_vinfo;
+ struct fb_var_screeninfo saved_vinfo;
+ int saved_cmaplen;
+ __u16 *saved_cmap;
+
+ int current_vt;
+ int saved_vt;
+ int keyboard_fd;
+ int saved_kbd_mode;
+ struct termios saved_kbd_termios;
+
+ int mouse_fd;
+#if SDL_INPUT_TSLIB
+ struct tsdev *ts_dev;
+#endif
+
+ char *mapped_mem;
+ char *shadow_mem;
+ int mapped_memlen;
+ int mapped_offset;
+ char *mapped_io;
+ long mapped_iolen;
+ int flip_page;
+ char *flip_address[2];
+ int rotate;
+ int shadow_fb; /* Tells whether a shadow is being used. */
+ FB_bitBlit *blitFunc;
+ int physlinebytes; /* Length of a line in bytes in physical fb */
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+ vidmem_bucket surfaces;
+ int surfaces_memtotal;
+ int surfaces_memleft;
+
+ SDL_mutex *hw_lock;
+ int switched_away;
+ struct fb_var_screeninfo screen_vinfo;
+ Uint32 screen_arealen;
+ Uint8 *screen_contents;
+ __u16 screen_palette[3*256];
+
+ void (*wait_vbl)(_THIS);
+ void (*wait_idle)(_THIS);
+};
+/* Old variable names */
+#define console_fd (this->hidden->console_fd)
+#define current_vt (this->hidden->current_vt)
+#define saved_vt (this->hidden->saved_vt)
+#define keyboard_fd (this->hidden->keyboard_fd)
+#define saved_kbd_mode (this->hidden->saved_kbd_mode)
+#define saved_kbd_termios (this->hidden->saved_kbd_termios)
+#define mouse_fd (this->hidden->mouse_fd)
+#if SDL_INPUT_TSLIB
+#define ts_dev (this->hidden->ts_dev)
+#endif
+#define cache_vinfo (this->hidden->cache_vinfo)
+#define saved_vinfo (this->hidden->saved_vinfo)
+#define saved_cmaplen (this->hidden->saved_cmaplen)
+#define saved_cmap (this->hidden->saved_cmap)
+#define mapped_mem (this->hidden->mapped_mem)
+#define shadow_mem (this->hidden->shadow_mem)
+#define mapped_memlen (this->hidden->mapped_memlen)
+#define mapped_offset (this->hidden->mapped_offset)
+#define mapped_io (this->hidden->mapped_io)
+#define mapped_iolen (this->hidden->mapped_iolen)
+#define flip_page (this->hidden->flip_page)
+#define flip_address (this->hidden->flip_address)
+#define rotate (this->hidden->rotate)
+#define shadow_fb (this->hidden->shadow_fb)
+#define blitFunc (this->hidden->blitFunc)
+#define physlinebytes (this->hidden->physlinebytes)
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define surfaces (this->hidden->surfaces)
+#define surfaces_memtotal (this->hidden->surfaces_memtotal)
+#define surfaces_memleft (this->hidden->surfaces_memleft)
+#define hw_lock (this->hidden->hw_lock)
+#define switched_away (this->hidden->switched_away)
+#define screen_vinfo (this->hidden->screen_vinfo)
+#define screen_arealen (this->hidden->screen_arealen)
+#define screen_contents (this->hidden->screen_contents)
+#define screen_palette (this->hidden->screen_palette)
+#define wait_vbl (this->hidden->wait_vbl)
+#define wait_idle (this->hidden->wait_idle)
+
+/* Accelerator types that are supported by the driver, but are not
+ necessarily in the kernel headers on the system we compile on.
+*/
+#ifndef FB_ACCEL_MATROX_MGAG400
+#define FB_ACCEL_MATROX_MGAG400 26 /* Matrox G400 */
+#endif
+#ifndef FB_ACCEL_3DFX_BANSHEE
+#define FB_ACCEL_3DFX_BANSHEE 31 /* 3Dfx Banshee */
+#endif
+
+/* These functions are defined in SDL_fbvideo.c */
+extern void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area);
+extern void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area);
+
+/* These are utility functions for working with video surfaces */
+
+static __inline__ void FB_AddBusySurface(SDL_Surface *surface)
+{
+ ((vidmem_bucket *)surface->hwdata)->dirty = 1;
+}
+
+static __inline__ int FB_IsSurfaceBusy(SDL_Surface *surface)
+{
+ return ((vidmem_bucket *)surface->hwdata)->dirty;
+}
+
+static __inline__ void FB_WaitBusySurfaces(_THIS)
+{
+ vidmem_bucket *bucket;
+
+ /* Wait for graphic operations to complete */
+ wait_idle(this);
+
+ /* Clear all surface dirty bits */
+ for ( bucket=&surfaces; bucket; bucket=bucket->next ) {
+ bucket->dirty = 0;
+ }
+}
+
+static __inline__ void FB_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y)
+{
+ *x = (long)((char *)dst->pixels - mapped_mem)%this->screen->pitch;
+ *y = (long)((char *)dst->pixels - mapped_mem)/this->screen->pitch;
+ if ( dst == this->screen ) {
+ *x += this->offset_x;
+ *y += this->offset_y;
+ }
+}
+
+#endif /* _SDL_fbvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/matrox_mmio.h b/distrib/sdl-1.2.15/src/video/fbcon/matrox_mmio.h
new file mode 100644
index 0000000..a1cf203
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/matrox_mmio.h
@@ -0,0 +1,51 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* MGA register definitions */
+
+#include "matrox_regs.h"
+
+/* MGA control macros */
+
+#define mga_in8(reg) *(volatile Uint8 *)(mapped_io + (reg))
+#define mga_in32(reg) *(volatile Uint32 *)(mapped_io + (reg))
+
+#define mga_out8(reg,v) *(volatile Uint8 *)(mapped_io + (reg)) = v;
+#define mga_out32(reg,v) *(volatile Uint32 *)(mapped_io + (reg)) = v;
+
+
+/* Wait for fifo space */
+#define mga_wait(space) \
+{ \
+ while ( mga_in8(MGAREG_FIFOSTATUS) < space ) \
+ ; \
+}
+
+
+/* Wait for idle accelerator */
+#define mga_waitidle() \
+{ \
+ while ( mga_in32(MGAREG_STATUS) & 0x10000 ) \
+ ; \
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/matrox_regs.h b/distrib/sdl-1.2.15/src/video/fbcon/matrox_regs.h
new file mode 100644
index 0000000..d570b0c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/matrox_regs.h
@@ -0,0 +1,376 @@
+
+/*
+ * MGA Millennium (MGA2064W) functions
+ * MGA Mystique (MGA1064SG) functions
+ *
+ * Copyright 1996 The XFree86 Project, Inc.
+ *
+ * Authors
+ * Dirk Hohndel
+ * hohndel@XFree86.Org
+ * David Dawes
+ * dawes@XFree86.Org
+ * Contributors:
+ * Guy DESBIEF, Aix-en-provence, France
+ * g.desbief@aix.pacwan.net
+ * MGA1064SG Mystique register file
+ */
+
+
+#ifndef _MGA_REG_H_
+#define _MGA_REG_H_
+
+#define MGAREG_DWGCTL 0x1c00
+#define MGAREG_MACCESS 0x1c04
+/* the following is a mystique only register */
+#define MGAREG_MCTLWTST 0x1c08
+#define MGAREG_ZORG 0x1c0c
+
+#define MGAREG_PAT0 0x1c10
+#define MGAREG_PAT1 0x1c14
+#define MGAREG_PLNWT 0x1c1c
+
+#define MGAREG_BCOL 0x1c20
+#define MGAREG_FCOL 0x1c24
+
+#define MGAREG_SRC0 0x1c30
+#define MGAREG_SRC1 0x1c34
+#define MGAREG_SRC2 0x1c38
+#define MGAREG_SRC3 0x1c3c
+
+#define MGAREG_XYSTRT 0x1c40
+#define MGAREG_XYEND 0x1c44
+
+#define MGAREG_SHIFT 0x1c50
+/* the following is a mystique only register */
+#define MGAREG_DMAPAD 0x1c54
+#define MGAREG_SGN 0x1c58
+#define MGAREG_LEN 0x1c5c
+
+#define MGAREG_AR0 0x1c60
+#define MGAREG_AR1 0x1c64
+#define MGAREG_AR2 0x1c68
+#define MGAREG_AR3 0x1c6c
+#define MGAREG_AR4 0x1c70
+#define MGAREG_AR5 0x1c74
+#define MGAREG_AR6 0x1c78
+
+#define MGAREG_CXBNDRY 0x1c80
+#define MGAREG_FXBNDRY 0x1c84
+#define MGAREG_YDSTLEN 0x1c88
+#define MGAREG_PITCH 0x1c8c
+
+#define MGAREG_YDST 0x1c90
+#define MGAREG_YDSTORG 0x1c94
+#define MGAREG_YTOP 0x1c98
+#define MGAREG_YBOT 0x1c9c
+
+#define MGAREG_CXLEFT 0x1ca0
+#define MGAREG_CXRIGHT 0x1ca4
+#define MGAREG_FXLEFT 0x1ca8
+#define MGAREG_FXRIGHT 0x1cac
+
+#define MGAREG_XDST 0x1cb0
+
+#define MGAREG_DR0 0x1cc0
+#define MGAREG_DR1 0x1cc4
+#define MGAREG_DR2 0x1cc8
+#define MGAREG_DR3 0x1ccc
+
+#define MGAREG_DR4 0x1cd0
+#define MGAREG_DR5 0x1cd4
+#define MGAREG_DR6 0x1cd8
+#define MGAREG_DR7 0x1cdc
+
+#define MGAREG_DR8 0x1ce0
+#define MGAREG_DR9 0x1ce4
+#define MGAREG_DR10 0x1ce8
+#define MGAREG_DR11 0x1cec
+
+#define MGAREG_DR12 0x1cf0
+#define MGAREG_DR13 0x1cf4
+#define MGAREG_DR14 0x1cf8
+#define MGAREG_DR15 0x1cfc
+
+#define MGAREG_SRCORG 0x2cb4
+#define MGAREG_DSTORG 0x2cb8
+
+/* add or or this to one of the previous "power registers" to start
+ the drawing engine */
+
+#define MGAREG_EXEC 0x0100
+
+#define MGAREG_FIFOSTATUS 0x1e10
+#define MGAREG_STATUS 0x1e14
+#define MGAREG_ICLEAR 0x1e18
+#define MGAREG_IEN 0x1e1c
+
+#define MGAREG_VCOUNT 0x1e20
+
+#define MGAREG_Reset 0x1e40
+
+#define MGAREG_OPMODE 0x1e54
+
+/* OPMODE register additives */
+
+#define MGAOPM_DMA_GENERAL (0x00 << 2)
+#define MGAOPM_DMA_BLIT (0x01 << 2)
+#define MGAOPM_DMA_VECTOR (0x10 << 2)
+
+/* DWGCTL register additives */
+
+/* Lines */
+
+#define MGADWG_LINE_OPEN 0x00
+#define MGADWG_AUTOLINE_OPEN 0x01
+#define MGADWG_LINE_CLOSE 0x02
+#define MGADWG_AUTOLINE_CLOSE 0x03
+
+/* Trapezoids */
+#define MGADWG_TRAP 0x04
+#define MGADWG_TEXTURE_TRAP 0x05
+
+/* BitBlts */
+
+#define MGADWG_BITBLT 0x08
+#define MGADWG_FBITBLT 0x0c
+#define MGADWG_ILOAD 0x09
+#define MGADWG_ILOAD_SCALE 0x0d
+#define MGADWG_ILOAD_FILTER 0x0f
+#define MGADWG_IDUMP 0x0a
+
+/* atype access to WRAM */
+
+#define MGADWG_RPL ( 0x00 << 4 )
+#define MGADWG_RSTR ( 0x01 << 4 )
+#define MGADWG_ZI ( 0x03 << 4 )
+#define MGADWG_BLK ( 0x04 << 4 )
+#define MGADWG_I ( 0x07 << 4 )
+
+/* specifies whether bit blits are linear or xy */
+#define MGADWG_LINEAR ( 0x01 << 7 )
+
+/* z drawing mode. use MGADWG_NOZCMP for always */
+
+#define MGADWG_NOZCMP ( 0x00 << 8 )
+#define MGADWG_ZE ( 0x02 << 8 )
+#define MGADWG_ZNE ( 0x03 << 8 )
+#define MGADWG_ZLT ( 0x04 << 8 )
+#define MGADWG_ZLTE ( 0x05 << 8 )
+#define MGADWG_GT ( 0x06 << 8 )
+#define MGADWG_GTE ( 0x07 << 8 )
+
+/* use this to force colour expansion circuitry to do its stuff */
+
+#define MGADWG_SOLID ( 0x01 << 11 )
+
+/* ar register at zero */
+
+#define MGADWG_ARZERO ( 0x01 << 12 )
+
+#define MGADWG_SGNZERO ( 0x01 << 13 )
+
+#define MGADWG_SHIFTZERO ( 0x01 << 14 )
+
+/* See table on 4-43 for bop ALU operations */
+
+/* See table on 4-44 for translucidity masks */
+
+#define MGADWG_BMONOLEF ( 0x00 << 25 )
+#define MGADWG_BMONOWF ( 0x04 << 25 )
+#define MGADWG_BPLAN ( 0x01 << 25 )
+
+/* note that if bfcol is specified and you're doing a bitblt, it causes
+ a fbitblt to be performed, so check that you obey the fbitblt rules */
+
+#define MGADWG_BFCOL ( 0x02 << 25 )
+#define MGADWG_BUYUV ( 0x0e << 25 )
+#define MGADWG_BU32BGR ( 0x03 << 25 )
+#define MGADWG_BU32RGB ( 0x07 << 25 )
+#define MGADWG_BU24BGR ( 0x0b << 25 )
+#define MGADWG_BU24RGB ( 0x0f << 25 )
+
+#define MGADWG_REPLACE 0x000C0000 /* From Linux kernel sources */
+#define MGADWG_PATTERN ( 0x01 << 29 )
+#define MGADWG_TRANSC ( 0x01 << 30 )
+#define MGADWG_NOCLIP ( 0x01 << 31 )
+#define MGAREG_MISC_WRITE 0x3c2
+#define MGAREG_MISC_READ 0x3cc
+#define MGAREG_MISC_IOADSEL (0x1 << 0)
+#define MGAREG_MISC_RAMMAPEN (0x1 << 1)
+#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
+#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
+#define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
+#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
+
+/* MMIO VGA registers */
+#define MGAREG_CRTC_INDEX 0x1fd4
+#define MGAREG_CRTC_DATA 0x1fd5
+#define MGAREG_CRTCEXT_INDEX 0x1fde
+#define MGAREG_CRTCEXT_DATA 0x1fdf
+
+
+/* MGA bits for registers PCI_OPTION_REG */
+#define MGA1064_OPT_SYS_CLK_PCI ( 0x00 << 0 )
+#define MGA1064_OPT_SYS_CLK_PLL ( 0x01 << 0 )
+#define MGA1064_OPT_SYS_CLK_EXT ( 0x02 << 0 )
+#define MGA1064_OPT_SYS_CLK_MSK ( 0x03 << 0 )
+
+#define MGA1064_OPT_SYS_CLK_DIS ( 0x01 << 2 )
+#define MGA1064_OPT_G_CLK_DIV_1 ( 0x01 << 3 )
+#define MGA1064_OPT_M_CLK_DIV_1 ( 0x01 << 4 )
+
+#define MGA1064_OPT_SYS_PLL_PDN ( 0x01 << 5 )
+#define MGA1064_OPT_VGA_ION ( 0x01 << 8 )
+
+/* MGA registers in PCI config space */
+#define PCI_MGA_INDEX 0x44
+#define PCI_MGA_DATA 0x48
+#define PCI_MGA_OPTION2 0x50
+#define PCI_MGA_OPTION3 0x54
+
+#define RAMDAC_OFFSET 0x3c00
+
+/* TVP3026 direct registers */
+
+#define TVP3026_INDEX 0x00
+#define TVP3026_WADR_PAL 0x00
+#define TVP3026_COL_PAL 0x01
+#define TVP3026_PIX_RD_MSK 0x02
+#define TVP3026_RADR_PAL 0x03
+#define TVP3026_CUR_COL_ADDR 0x04
+#define TVP3026_CUR_COL_DATA 0x05
+#define TVP3026_DATA 0x0a
+#define TVP3026_CUR_RAM 0x0b
+#define TVP3026_CUR_XLOW 0x0c
+#define TVP3026_CUR_XHI 0x0d
+#define TVP3026_CUR_YLOW 0x0e
+#define TVP3026_CUR_YHI 0x0f
+
+/* TVP3026 indirect registers */
+
+#define TVP3026_SILICON_REV 0x01
+#define TVP3026_CURSOR_CTL 0x06
+#define TVP3026_LATCH_CTL 0x0f
+#define TVP3026_TRUE_COLOR_CTL 0x18
+#define TVP3026_MUX_CTL 0x19
+#define TVP3026_CLK_SEL 0x1a
+#define TVP3026_PAL_PAGE 0x1c
+#define TVP3026_GEN_CTL 0x1d
+#define TVP3026_MISC_CTL 0x1e
+#define TVP3026_GEN_IO_CTL 0x2a
+#define TVP3026_GEN_IO_DATA 0x2b
+#define TVP3026_PLL_ADDR 0x2c
+#define TVP3026_PIX_CLK_DATA 0x2d
+#define TVP3026_MEM_CLK_DATA 0x2e
+#define TVP3026_LOAD_CLK_DATA 0x2f
+#define TVP3026_KEY_RED_LOW 0x32
+#define TVP3026_KEY_RED_HI 0x33
+#define TVP3026_KEY_GREEN_LOW 0x34
+#define TVP3026_KEY_GREEN_HI 0x35
+#define TVP3026_KEY_BLUE_LOW 0x36
+#define TVP3026_KEY_BLUE_HI 0x37
+#define TVP3026_KEY_CTL 0x38
+#define TVP3026_MCLK_CTL 0x39
+#define TVP3026_SENSE_TEST 0x3a
+#define TVP3026_TEST_DATA 0x3b
+#define TVP3026_CRC_LSB 0x3c
+#define TVP3026_CRC_MSB 0x3d
+#define TVP3026_CRC_CTL 0x3e
+#define TVP3026_ID 0x3f
+#define TVP3026_RESET 0xff
+
+
+/* MGA1064 DAC Register file */
+/* MGA1064 direct registers */
+
+#define MGA1064_INDEX 0x00
+#define MGA1064_WADR_PAL 0x00
+#define MGA1064_COL_PAL 0x01
+#define MGA1064_PIX_RD_MSK 0x02
+#define MGA1064_RADR_PAL 0x03
+#define MGA1064_DATA 0x0a
+
+#define MGA1064_CUR_XLOW 0x0c
+#define MGA1064_CUR_XHI 0x0d
+#define MGA1064_CUR_YLOW 0x0e
+#define MGA1064_CUR_YHI 0x0f
+
+/* MGA1064 indirect registers */
+#define MGA1064_CURSOR_BASE_ADR_LOW 0x04
+#define MGA1064_CURSOR_BASE_ADR_HI 0x05
+#define MGA1064_CURSOR_CTL 0x06
+#define MGA1064_CURSOR_COL0_RED 0x08
+#define MGA1064_CURSOR_COL0_GREEN 0x09
+#define MGA1064_CURSOR_COL0_BLUE 0x0a
+
+#define MGA1064_CURSOR_COL1_RED 0x0c
+#define MGA1064_CURSOR_COL1_GREEN 0x0d
+#define MGA1064_CURSOR_COL1_BLUE 0x0e
+
+#define MGA1064_CURSOR_COL2_RED 0x010
+#define MGA1064_CURSOR_COL2_GREEN 0x011
+#define MGA1064_CURSOR_COL2_BLUE 0x012
+
+#define MGA1064_VREF_CTL 0x018
+
+#define MGA1064_MUL_CTL 0x19
+#define MGA1064_MUL_CTL_8bits 0x0
+#define MGA1064_MUL_CTL_15bits 0x01
+#define MGA1064_MUL_CTL_16bits 0x02
+#define MGA1064_MUL_CTL_24bits 0x03
+#define MGA1064_MUL_CTL_32bits 0x04
+#define MGA1064_MUL_CTL_2G8V16bits 0x05
+#define MGA1064_MUL_CTL_G16V16bits 0x06
+#define MGA1064_MUL_CTL_32_24bits 0x07
+
+#define MGAGDAC_XVREFCTRL 0x18
+#define MGA1064_PIX_CLK_CTL 0x1a
+#define MGA1064_PIX_CLK_CTL_CLK_DIS ( 0x01 << 2 )
+#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN ( 0x01 << 3 )
+#define MGA1064_PIX_CLK_CTL_SEL_PCI ( 0x00 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_PLL ( 0x01 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_EXT ( 0x02 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_MSK ( 0x03 << 0 )
+
+#define MGA1064_GEN_CTL 0x1d
+#define MGA1064_MISC_CTL 0x1e
+#define MGA1064_MISC_CTL_DAC_POW_DN ( 0x01 << 0 )
+#define MGA1064_MISC_CTL_VGA ( 0x01 << 1 )
+#define MGA1064_MISC_CTL_DIS_CON ( 0x03 << 1 )
+#define MGA1064_MISC_CTL_MAFC ( 0x02 << 1 )
+#define MGA1064_MISC_CTL_VGA8 ( 0x01 << 3 )
+#define MGA1064_MISC_CTL_DAC_RAM_CS ( 0x01 << 4 )
+
+#define MGA1064_GEN_IO_CTL 0x2a
+#define MGA1064_GEN_IO_DATA 0x2b
+#define MGA1064_SYS_PLL_M 0x2c
+#define MGA1064_SYS_PLL_N 0x2d
+#define MGA1064_SYS_PLL_P 0x2e
+#define MGA1064_SYS_PLL_STAT 0x2f
+#define MGA1064_ZOOM_CTL 0x38
+#define MGA1064_SENSE_TST 0x3a
+
+#define MGA1064_CRC_LSB 0x3c
+#define MGA1064_CRC_MSB 0x3d
+#define MGA1064_CRC_CTL 0x3e
+#define MGA1064_COL_KEY_MSK_LSB 0x40
+#define MGA1064_COL_KEY_MSK_MSB 0x41
+#define MGA1064_COL_KEY_LSB 0x42
+#define MGA1064_COL_KEY_MSB 0x43
+#define MGA1064_PIX_PLLA_M 0x44
+#define MGA1064_PIX_PLLA_N 0x45
+#define MGA1064_PIX_PLLA_P 0x46
+#define MGA1064_PIX_PLLB_M 0x48
+#define MGA1064_PIX_PLLB_N 0x49
+#define MGA1064_PIX_PLLB_P 0x4a
+#define MGA1064_PIX_PLLC_M 0x4c
+#define MGA1064_PIX_PLLC_N 0x4d
+#define MGA1064_PIX_PLLC_P 0x4e
+
+#define MGA1064_PIX_PLL_STAT 0x4f
+
+#endif
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/riva_mmio.h b/distrib/sdl-1.2.15/src/video/fbcon/riva_mmio.h
new file mode 100644
index 0000000..e926167
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/riva_mmio.h
@@ -0,0 +1,449 @@
+/***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+\***************************************************************************/
+
+#ifndef __RIVA_HW_H__
+#define __RIVA_HW_H__
+#define RIVA_SW_VERSION 0x00010003
+
+/*
+ * Typedefs to force certain sized values.
+ */
+typedef Uint8 U008;
+typedef Uint16 U016;
+typedef Uint32 U032;
+
+/*
+ * HW access macros.
+ */
+#define NV_WR08(p,i,d) (((U008 *)(p))[i]=(d))
+#define NV_RD08(p,i) (((U008 *)(p))[i])
+#define NV_WR16(p,i,d) (((U016 *)(p))[(i)/2]=(d))
+#define NV_RD16(p,i) (((U016 *)(p))[(i)/2])
+#define NV_WR32(p,i,d) (((U032 *)(p))[(i)/4]=(d))
+#define NV_RD32(p,i) (((U032 *)(p))[(i)/4])
+#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
+#define VGA_RD08(p,i) NV_RD08(p,i)
+
+/*
+ * Define supported architectures.
+ */
+#define NV_ARCH_03 0x03
+#define NV_ARCH_04 0x04
+#define NV_ARCH_10 0x10
+/***************************************************************************\
+* *
+* FIFO registers. *
+* *
+\***************************************************************************/
+
+/*
+ * Raster OPeration. Windows style ROP3.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BB];
+ U032 Rop3;
+} RivaRop;
+/*
+ * 8X8 Monochrome pattern.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BD];
+ U032 Shape;
+ U032 reserved03[0x001];
+ U032 Color0;
+ U032 Color1;
+ U032 Monochrome[2];
+} RivaPattern;
+/*
+ * Scissor clip rectangle.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BB];
+ U032 TopLeft;
+ U032 WidthHeight;
+} RivaClip;
+/*
+ * 2D filled rectangle.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop[1];
+ U032 reserved01[0x0BC];
+ U032 Color;
+ U032 reserved03[0x03E];
+ U032 TopLeft;
+ U032 WidthHeight;
+} RivaRectangle;
+/*
+ * 2D screen-screen BLT.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BB];
+ U032 TopLeftSrc;
+ U032 TopLeftDst;
+ U032 WidthHeight;
+} RivaScreenBlt;
+/*
+ * 2D pixel BLT.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop[1];
+ U032 reserved01[0x0BC];
+ U032 TopLeft;
+ U032 WidthHeight;
+ U032 WidthHeightIn;
+ U032 reserved02[0x03C];
+ U032 Pixels;
+} RivaPixmap;
+/*
+ * Filled rectangle combined with monochrome expand. Useful for glyphs.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BB];
+ U032 reserved03[(0x040)-1];
+ U032 Color1A;
+ struct
+ {
+ U032 TopLeft;
+ U032 WidthHeight;
+ } UnclippedRectangle[64];
+ U032 reserved04[(0x080)-3];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipB;
+ U032 Color1B;
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClippedRectangle[64];
+ U032 reserved05[(0x080)-5];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipC;
+ U032 Color1C;
+ U032 WidthHeightC;
+ U032 PointC;
+ U032 MonochromeData1C;
+ U032 reserved06[(0x080)+121];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipD;
+ U032 Color1D;
+ U032 WidthHeightInD;
+ U032 WidthHeightOutD;
+ U032 PointD;
+ U032 MonochromeData1D;
+ U032 reserved07[(0x080)+120];
+ struct
+ {
+ U032 TopLeft;
+ U032 BottomRight;
+ } ClipE;
+ U032 Color0E;
+ U032 Color1E;
+ U032 WidthHeightInE;
+ U032 WidthHeightOutE;
+ U032 PointE;
+ U032 MonochromeData01E;
+} RivaBitmap;
+/*
+ * 3D textured, Z buffered triangle.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BC];
+ U032 TextureOffset;
+ U032 TextureFormat;
+ U032 TextureFilter;
+ U032 FogColor;
+/* This is a problem on LynxOS */
+#ifdef Control
+#undef Control
+#endif
+ U032 Control;
+ U032 AlphaTest;
+ U032 reserved02[0x339];
+ U032 FogAndIndex;
+ U032 Color;
+ float ScreenX;
+ float ScreenY;
+ float ScreenZ;
+ float EyeM;
+ float TextureS;
+ float TextureT;
+} RivaTexturedTriangle03;
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BB];
+ U032 ColorKey;
+ U032 TextureOffset;
+ U032 TextureFormat;
+ U032 TextureFilter;
+ U032 Blend;
+/* This is a problem on LynxOS */
+#ifdef Control
+#undef Control
+#endif
+ U032 Control;
+ U032 FogColor;
+ U032 reserved02[0x39];
+ struct
+ {
+ float ScreenX;
+ float ScreenY;
+ float ScreenZ;
+ float EyeM;
+ U032 Color;
+ U032 Specular;
+ float TextureS;
+ float TextureT;
+ } Vertex[16];
+ U032 DrawTriangle3D;
+} RivaTexturedTriangle05;
+/*
+ * 2D line.
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop[1];
+ U032 reserved01[0x0BC];
+ U032 Color; /* source color 0304-0307*/
+ U032 Reserved02[0x03e];
+ struct { /* start aliased methods in array 0400- */
+ U032 point0; /* y_x S16_S16 in pixels 0- 3*/
+ U032 point1; /* y_x S16_S16 in pixels 4- 7*/
+ } Lin[16]; /* end of aliased methods in array -047f*/
+ struct { /* start aliased methods in array 0480- */
+ U032 point0X; /* in pixels, 0 at left 0- 3*/
+ U032 point0Y; /* in pixels, 0 at top 4- 7*/
+ U032 point1X; /* in pixels, 0 at left 8- b*/
+ U032 point1Y; /* in pixels, 0 at top c- f*/
+ } Lin32[8]; /* end of aliased methods in array -04ff*/
+ U032 PolyLin[32]; /* y_x S16_S16 in pixels 0500-057f*/
+ struct { /* start aliased methods in array 0580- */
+ U032 x; /* in pixels, 0 at left 0- 3*/
+ U032 y; /* in pixels, 0 at top 4- 7*/
+ } PolyLin32[16]; /* end of aliased methods in array -05ff*/
+ struct { /* start aliased methods in array 0600- */
+ U032 color; /* source color 0- 3*/
+ U032 point; /* y_x S16_S16 in pixels 4- 7*/
+ } ColorPolyLin[16]; /* end of aliased methods in array -067f*/
+} RivaLine;
+/*
+ * 2D/3D surfaces
+ */
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BE];
+ U032 Offset;
+} RivaSurface;
+typedef volatile struct
+{
+ U032 reserved00[4];
+ U016 FifoFree;
+ U016 Nop;
+ U032 reserved01[0x0BD];
+ U032 Pitch;
+ U032 RenderBufferOffset;
+ U032 ZBufferOffset;
+} RivaSurface3D;
+
+/***************************************************************************\
+* *
+* Virtualized RIVA H/W interface. *
+* *
+\***************************************************************************/
+
+struct _riva_hw_inst;
+struct _riva_hw_state;
+/*
+ * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
+ */
+typedef struct _riva_hw_inst
+{
+ /*
+ * Chip specific settings.
+ */
+ U032 Architecture;
+ U032 Version;
+ U032 CrystalFreqKHz;
+ U032 RamAmountKBytes;
+ U032 MaxVClockFreqKHz;
+ U032 RamBandwidthKBytesPerSec;
+ U032 EnableIRQ;
+ U032 IO;
+ U032 VBlankBit;
+ U032 FifoFreeCount;
+ U032 FifoEmptyCount;
+ /*
+ * Non-FIFO registers.
+ */
+ volatile U032 *PCRTC;
+ volatile U032 *PRAMDAC;
+ volatile U032 *PFB;
+ volatile U032 *PFIFO;
+ volatile U032 *PGRAPH;
+ volatile U032 *PEXTDEV;
+ volatile U032 *PTIMER;
+ volatile U032 *PMC;
+ volatile U032 *PRAMIN;
+ volatile U032 *FIFO;
+ volatile U032 *CURSOR;
+ volatile U032 *CURSORPOS;
+ volatile U032 *VBLANKENABLE;
+ volatile U032 *VBLANK;
+ volatile U008 *PCIO;
+ volatile U008 *PVIO;
+ volatile U008 *PDIO;
+ /*
+ * Common chip functions.
+ */
+ int (*Busy)(struct _riva_hw_inst *);
+ void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int,int,int,int,int,int,int,int);
+ void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*SetStartAddress)(struct _riva_hw_inst *,U032);
+ void (*SetSurfaces2D)(struct _riva_hw_inst *,U032,U032);
+ void (*SetSurfaces3D)(struct _riva_hw_inst *,U032,U032);
+ int (*ShowHideCursor)(struct _riva_hw_inst *,int);
+ void (*LockUnlock)(struct _riva_hw_inst *, int);
+ /*
+ * Current extended mode settings.
+ */
+ struct _riva_hw_state *CurrentState;
+ /*
+ * FIFO registers.
+ */
+ RivaRop *Rop;
+ RivaPattern *Patt;
+ RivaClip *Clip;
+ RivaPixmap *Pixmap;
+ RivaScreenBlt *Blt;
+ RivaBitmap *Bitmap;
+ RivaLine *Line;
+ RivaTexturedTriangle03 *Tri03;
+ RivaTexturedTriangle05 *Tri05;
+} RIVA_HW_INST;
+/*
+ * Extended mode state information.
+ */
+typedef struct _riva_hw_state
+{
+ U032 bpp;
+ U032 width;
+ U032 height;
+ U032 repaint0;
+ U032 repaint1;
+ U032 screen;
+ U032 pixel;
+ U032 horiz;
+ U032 arbitration0;
+ U032 arbitration1;
+ U032 vpll;
+ U032 pllsel;
+ U032 general;
+ U032 config;
+ U032 cursor0;
+ U032 cursor1;
+ U032 cursor2;
+ U032 offset0;
+ U032 offset1;
+ U032 offset2;
+ U032 offset3;
+ U032 pitch0;
+ U032 pitch1;
+ U032 pitch2;
+ U032 pitch3;
+} RIVA_HW_STATE;
+
+/*
+ * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
+ */
+
+#define RIVA_FIFO_FREE(hwptr,cnt) \
+{ \
+ while (FifoFreeCount < (cnt)) \
+ FifoFreeCount = hwptr->FifoFree >> 2; \
+ FifoFreeCount -= (cnt); \
+}
+#endif /* __RIVA_HW_H__ */
+
diff --git a/distrib/sdl-1.2.15/src/video/fbcon/riva_regs.h b/distrib/sdl-1.2.15/src/video/fbcon/riva_regs.h
new file mode 100644
index 0000000..5324562
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/fbcon/riva_regs.h
@@ -0,0 +1,43 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 _RIVA_REGS_H
+#define _RIVA_REGS_H
+
+/* This information comes from the XFree86 NVidia hardware driver */
+
+/* mapped_io register offsets */
+#define PGRAPH_OFFSET 0x00400000
+#define FIFO_OFFSET 0x00800000
+#define ROP_OFFSET FIFO_OFFSET+0x00000000
+#define CLIP_OFFSET FIFO_OFFSET+0x00002000
+#define PATT_OFFSET FIFO_OFFSET+0x00004000
+#define PIXMAP_OFFSET FIFO_OFFSET+0x00006000
+#define BLT_OFFSET FIFO_OFFSET+0x00008000
+#define BITMAP_OFFSET FIFO_OFFSET+0x0000A000
+#define LINE_OFFSET FIFO_OFFSET+0x0000C000
+#define TRI03_OFFSET FIFO_OFFSET+0x0000E000
+#define PCIO_OFFSET 0x00601000
+
+#endif /* _RIVA_REGS_H */
+
diff --git a/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.c b/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.c
new file mode 100644
index 0000000..86deadc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.c
@@ -0,0 +1,1287 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Pocket PC GAPI SDL video driver implementation;
+Implemented by Dmitry Yakimov - support@activekitten.com
+Inspired by http://arisme.free.fr/ports/SDL.php
+*/
+
+// TODO: copy surface on window when lost focus
+// TODO: test buttons rotation
+// TODO: test on be300 and HPC ( check WinDib fullscreen keys catching )
+// TODO: test on smartphones
+// TODO: windib on SH3 PPC2000 landscape test
+// TODO: optimize 8bpp landscape mode
+
+// there is some problems in runnings apps from a device landscape mode
+// due to WinCE bugs. Some works and some - does not.
+// TODO: finish Axim Dell X30 and user landscape mode, device landscape mode
+// TODO: finish Axim Dell X30 user portrait, device landscape stylus conversion
+// TODO: fix running GAPI apps from landscape mode -
+// wince goes to portrait mode, but does not update video memory
+
+
+#include "SDL.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "../wincommon/SDL_syswm_c.h"
+#include "../wincommon/SDL_sysmouse_c.h"
+#include "../windib/SDL_dibevents_c.h"
+
+#include "../windib/SDL_gapidibvideo.h"
+#include "SDL_gapivideo.h"
+
+#define gapi this->hidden->gapiInfo
+
+#define GAPIVID_DRIVER_NAME "gapi"
+
+#if defined(DEBUG) || defined (_DEBUG) || defined(NDEBUG)
+#define REPORT_VIDEO_INFO 1
+#else
+#define REPORT_VIDEO_INFO 0
+#endif
+
+// for testing with GapiEmu
+#define USE_GAPI_EMU 0
+#define EMULATE_AXIM_X30 0
+#define WITHOUT_GAPI 0
+
+#if USE_GAPI_EMU && !REPORT_VIDEO_INFO
+#pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.")
+#endif
+
+#ifndef _T
+#define _T(x) L##x
+#endif
+
+#ifndef ASSERT
+#define ASSERT(x)
+#endif
+
+// defined and used in SDL_sysevents.c
+extern HINSTANCE aygshell;
+extern void SDL_UnregisterApp();
+extern int DIB_AddMode(_THIS, int bpp, int w, int h);
+
+/* Initialization/Query functions */
+static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GAPI_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Windows message handling functions, will not be processed */
+static void GAPI_Activate(_THIS, BOOL active, BOOL minimized);
+static void GAPI_RealizePalette(_THIS);
+static void GAPI_PaletteChanged(_THIS, HWND window);
+static void GAPI_WinPAINT(_THIS, HDC hdc);
+
+/* etc. */
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+static HMODULE g_hGapiLib = 0;
+#define LINK(type,name,import) \
+ if( g_hGapiLib ) \
+ name = (PFN##type)GetProcAddress( g_hGapiLib, _T(import) );
+
+static char g_bRawBufferAvailable = 0;
+
+/* GAPI driver bootstrap functions */
+
+/* hi res definitions */
+typedef struct _RawFrameBufferInfo
+{
+ WORD wFormat;
+ WORD wBPP;
+ VOID *pFramePointer;
+ int cxStride;
+ int cyStride;
+ int cxPixels;
+ int cyPixels;
+} RawFrameBufferInfo;
+
+static struct _RawFrameBufferInfo g_RawFrameBufferInfo = {0};
+
+#define GETRAWFRAMEBUFFER 0x00020001
+
+#define FORMAT_565 1
+#define FORMAT_555 2
+#define FORMAT_OTHER 3
+
+/* Dell Axim x30 hangs when we use GAPI from landscape,
+ so lets avoid using GxOpenDisplay there via GETGXINFO trick
+ It seems that GAPI subsystem use the same ExtEscape code.
+*/
+#define GETGXINFO 0x00020000
+
+typedef struct GXDeviceInfo
+{
+long Version; //00 (should filled with 100 before calling ExtEscape)
+void * pvFrameBuffer; //04
+unsigned long cbStride; //08
+unsigned long cxWidth; //0c
+unsigned long cyHeight; //10
+unsigned long cBPP; //14
+unsigned long ffFormat; //18
+char Unused[0x84-7*4];
+} GXDeviceInfo;
+
+static int GAPI_Available(void)
+{
+ // try to use VGA display, even on emulator
+ HDC hdc = GetDC(NULL);
+ int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&g_RawFrameBufferInfo);
+ ReleaseDC(NULL, hdc);
+ g_bRawBufferAvailable = result > 0;
+
+ //My Asus MyPAL 696 reports the RAWFRAMEBUFFER as available, but with a size of 0 x 0
+ if(g_RawFrameBufferInfo.cxPixels <= 0 || g_RawFrameBufferInfo.cyPixels <= 0){
+ g_bRawBufferAvailable = 0;
+ }
+
+#if WITHOUT_GAPI
+ return g_bRawBufferAvailable;
+#endif
+
+#if USE_GAPI_EMU
+ g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll"));
+ if( !g_hGapiLib )
+ {
+ SDL_SetError("Gapi Emu not found!");
+ }
+ return g_hGapiLib != 0;
+#endif
+
+ // try to find gx.dll
+ g_hGapiLib = LoadLibrary(_T("\\Windows\\gx.dll"));
+ if( !g_hGapiLib )
+ {
+ g_hGapiLib = LoadLibrary(_T("gx.dll"));
+ if( !g_hGapiLib ) return g_bRawBufferAvailable;
+ }
+
+ return(1);
+}
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ SDL_Rect *a = *(SDL_Rect **)va;
+ SDL_Rect *b = *(SDL_Rect **)vb;
+ if ( a->w == b->w )
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+
+static int GAPI_AddMode(_THIS, int bpp, int w, int h)
+{
+ SDL_Rect *mode;
+ int i, index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( bpp < 8 ) { /* Not supported */
+ return(0);
+ }
+ index = ((bpp+7)/8)-1;
+ for ( i=0; i<gapi->SDL_nummodes[index]; ++i ) {
+ mode = gapi->SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = gapi->SDL_nummodes[index];
+ gapi->SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(gapi->SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( gapi->SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ gapi->SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ gapi->SDL_modelist[index][next_mode] = mode;
+ gapi->SDL_modelist[index][next_mode+1] = NULL;
+ gapi->SDL_nummodes[index]++;
+
+ return(0);
+}
+
+static void GAPI_DeleteDevice(SDL_VideoDevice *device)
+{
+ if( g_hGapiLib )
+ {
+ FreeLibrary(g_hGapiLib);
+ g_hGapiLib = 0;
+ }
+ SDL_free(device->hidden->gapiInfo);
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *GAPI_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ if( !g_hGapiLib && !g_bRawBufferAvailable)
+ {
+ if( !GAPI_Available() )
+ {
+ SDL_SetError("GAPI dll is not found and VGA mode is not available!");
+ return 0;
+ }
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ if(device->hidden){
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ device->hidden->gapiInfo = (GapiInfo *)SDL_malloc((sizeof(GapiInfo)));
+ if(device->hidden->gapiInfo == NULL)
+ {
+ SDL_free(device->hidden);
+ device->hidden = NULL;
+ }
+ }
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden->gapiInfo, 0, (sizeof *device->hidden->gapiInfo));
+
+ /* Set the function pointers */
+ device->VideoInit = GAPI_VideoInit;
+ device->ListModes = GAPI_ListModes;
+ device->SetVideoMode = GAPI_SetVideoMode;
+ device->UpdateMouse = WIN_UpdateMouse;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = GAPI_SetColors;
+ device->UpdateRects = GAPI_UpdateRects;
+ device->VideoQuit = GAPI_VideoQuit;
+ device->AllocHWSurface = GAPI_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = GAPI_LockHWSurface;
+ device->UnlockHWSurface = GAPI_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = GAPI_FreeHWSurface;
+ device->SetCaption = WIN_SetWMCaption;
+ device->SetIcon = WIN_SetWMIcon;
+ device->IconifyWindow = WIN_IconifyWindow;
+ device->GrabInput = WIN_GrabInput;
+ device->GetWMInfo = WIN_GetWMInfo;
+ device->FreeWMCursor = WIN_FreeWMCursor;
+ device->CreateWMCursor = WIN_CreateWMCursor;
+ device->ShowWMCursor = WIN_ShowWMCursor;
+ device->WarpWMCursor = WIN_WarpWMCursor;
+ device->CheckMouseMode = WIN_CheckMouseMode;
+ device->InitOSKeymap = DIB_InitOSKeymap;
+ device->PumpEvents = DIB_PumpEvents;
+
+ /* Set up the windows message handling functions */
+ WIN_Activate = GAPI_Activate;
+ WIN_RealizePalette = GAPI_RealizePalette;
+ WIN_PaletteChanged = GAPI_PaletteChanged;
+ WIN_WinPAINT = GAPI_WinPAINT;
+ HandleMessage = DIB_HandleMessage;
+
+ device->free = GAPI_DeleteDevice;
+
+ /* Load gapi library */
+#define gx device->hidden->gapiInfo->gxFunc
+
+ LINK( GXOpenDisplay, gx.GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z" )
+ LINK( GXCloseDisplay, gx.GXCloseDisplay, "?GXCloseDisplay@@YAHXZ" )
+ LINK( GXBeginDraw, gx.GXBeginDraw, "?GXBeginDraw@@YAPAXXZ" )
+ LINK( GXEndDraw, gx.GXEndDraw, "?GXEndDraw@@YAHXZ" )
+ LINK( GXOpenInput, gx.GXOpenInput, "?GXOpenInput@@YAHXZ" )
+ LINK( GXCloseInput, gx.GXCloseInput, "?GXCloseInput@@YAHXZ" )
+ LINK( GXGetDisplayProperties, gx.GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ" )
+ LINK( GXGetDefaultKeys, gx.GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z" )
+ LINK( GXSuspend, gx.GXSuspend, "?GXSuspend@@YAHXZ" )
+ LINK( GXResume, gx.GXResume, "?GXResume@@YAHXZ" )
+ LINK( GXSetViewport, gx.GXSetViewport, "?GXSetViewport@@YAHKKKK@Z" )
+ LINK( GXIsDisplayDRAMBuffer, gx.GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ" )
+
+ /* wrong gapi.dll */
+ if( !gx.GXOpenDisplay )
+ {
+ if( g_hGapiLib )
+ {
+ FreeLibrary(g_hGapiLib);
+ g_hGapiLib = 0;
+ }
+ }
+
+ if( !gx.GXOpenDisplay && !g_bRawBufferAvailable)
+ {
+ SDL_SetError("Error: damaged or unknown gapi.dll!\n");
+ GAPI_DeleteDevice(device);
+ return 0;
+ }
+
+ return device;
+}
+
+VideoBootStrap GAPI_bootstrap = {
+ GAPIVID_DRIVER_NAME, "WinCE GAPI video driver",
+ GAPI_Available, GAPI_CreateDevice
+};
+
+static void FillStructs(_THIS, BOOL useVga)
+{
+#ifdef _ARM_
+ WCHAR oemstr[100];
+#endif
+ /* fill a device properties */
+
+ if( !useVga )
+ {
+ gapi->gxProperties = gapi->gxFunc.GXGetDisplayProperties();
+ gapi->needUpdate = 1;
+ gapi->hiresFix = 0;
+ gapi->useVga = 0;
+ gapi->useGXOpenDisplay = 1;
+
+#ifdef _ARM_
+ /* check some devices and extract addition info */
+ SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr ), oemstr, 0 );
+
+ // buggy iPaq38xx
+ if ((oemstr[12] == 'H') && (oemstr[13] == '3') && (oemstr[14] == '8') && (gapi->gxProperties.cbxPitch > 0))
+ {
+ gapi->videoMem = (PIXEL*)0xac0755a0;
+ gapi->gxProperties.cbxPitch = -640;
+ gapi->gxProperties.cbyPitch = 2;
+ gapi->needUpdate = 0;
+ }
+#if (EMULATE_AXIM_X30 == 0)
+ // buggy Dell Axim X30
+ if( _tcsncmp(oemstr, L"Dell Axim X30", 13) == 0 )
+#endif
+ {
+ GXDeviceInfo gxInfo = {0};
+ HDC hdc = GetDC(NULL);
+ int result;
+
+ gxInfo.Version = 100;
+ result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *)&gxInfo);
+ if( result > 0 )
+ {
+ gapi->useGXOpenDisplay = 0;
+ gapi->videoMem = gxInfo.pvFrameBuffer;
+ gapi->needUpdate = 0;
+ gapi->gxProperties.cbxPitch = 2;
+ gapi->gxProperties.cbyPitch = 480;
+ gapi->gxProperties.cxWidth = gxInfo.cxWidth;
+ gapi->gxProperties.cyHeight = gxInfo.cyHeight;
+ gapi->gxProperties.ffFormat = gxInfo.ffFormat;
+ }
+ }
+#endif
+ } else
+ {
+ gapi->needUpdate = 0;
+ gapi->hiresFix = 0;
+ gapi->gxProperties.cBPP = g_RawFrameBufferInfo.wBPP;
+ gapi->gxProperties.cbxPitch = g_RawFrameBufferInfo.cxStride;
+ gapi->gxProperties.cbyPitch = g_RawFrameBufferInfo.cyStride;
+ gapi->gxProperties.cxWidth = g_RawFrameBufferInfo.cxPixels;
+ gapi->gxProperties.cyHeight = g_RawFrameBufferInfo.cyPixels;
+ gapi->videoMem = g_RawFrameBufferInfo.pFramePointer;
+ gapi->useVga = 1;
+
+ switch( g_RawFrameBufferInfo.wFormat )
+ {
+ case FORMAT_565:
+ gapi->gxProperties.ffFormat = kfDirect565;
+ break;
+ case FORMAT_555:
+ gapi->gxProperties.ffFormat = kfDirect555;
+ break;
+ default:
+ /* unknown pixel format, try define by BPP! */
+ switch( g_RawFrameBufferInfo.wBPP )
+ {
+ case 4:
+ case 8:
+ gapi->gxProperties.ffFormat = kfDirect;
+ case 16:
+ gapi->gxProperties.ffFormat = kfDirect565;
+ default:
+ gapi->gxProperties.ffFormat = kfDirect;
+ break;
+ }
+ }
+ }
+
+ if( gapi->gxProperties.cBPP != 16 )
+ {
+ gapi->gapiOrientation = SDL_ORIENTATION_UP;
+ } else
+ if( (gapi->gxProperties.cbxPitch > 0) && (gapi->gxProperties.cbyPitch > 0 ))
+ {
+ gapi->gapiOrientation = SDL_ORIENTATION_UP;
+ } else
+ if( (gapi->gxProperties.cbxPitch > 0) && (gapi->gxProperties.cbyPitch < 0 ))
+ {
+ gapi->gapiOrientation = SDL_ORIENTATION_RIGHT; // ipaq 3660
+ } else
+ if( (gapi->gxProperties.cbxPitch < 0) && (gapi->gxProperties.cbyPitch > 0 ))
+ {
+ gapi->gapiOrientation = SDL_ORIENTATION_LEFT; // ipaq 3800
+ }
+}
+
+static void GAPI_CreatePalette(int ncolors, SDL_Color *colors)
+{
+ // Setup a custom color palette
+ BYTE buffer[ sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY) ];
+ int i;
+ LOGPALETTE* pLogical = (LOGPALETTE*)buffer;
+ PALETTEENTRY* entries = pLogical->palPalEntry;
+ HPALETTE hPalette;
+ HDC hdc;
+
+ for (i = 0; i < ncolors; ++i)
+ {
+ // Find intensity by replicating the bit patterns over a byte
+ entries[i].peRed = colors[i].r;
+ entries[i].peGreen = colors[i].g;
+ entries[i].peBlue = colors[i].b;
+ entries[i].peFlags = 0;
+ }
+
+ // Create the GDI palette object
+ pLogical->palVersion = 0x0300;
+ pLogical->palNumEntries = ncolors;
+
+ hPalette = CreatePalette( pLogical );
+ ASSERT(hPalette);
+
+
+ // Realize the palette
+ hdc = GetDC(0);
+
+ SelectPalette( hdc, hPalette, FALSE );
+ RealizePalette( hdc );
+
+ ReleaseDC( 0, hdc );
+ DeleteObject( hPalette );
+}
+
+int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i,bpp;
+
+ /* Create the window */
+ if ( DIB_CreateWindow(this) < 0 ) {
+ return(-1);
+ }
+
+ if( g_hGapiLib )
+ {
+ FillStructs(this, 0);
+
+ // SDL does not supports 2/4bpp mode, so use 16 bpp
+ bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;
+
+ /* set up normal and landscape mode */
+ GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth);
+ GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight);
+ }
+
+ /* add hi-res mode */
+ if( g_bRawBufferAvailable &&
+ !((gapi->gxProperties.cxWidth == (unsigned)g_RawFrameBufferInfo.cxPixels) && (gapi->gxProperties.cyHeight == (unsigned)g_RawFrameBufferInfo.cyPixels)))
+ {
+ FillStructs(this, 1);
+
+ // SDL does not supports 2/4bpp mode, so use 16 bpp
+ bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;
+
+ /* set up normal and landscape mode */
+ GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth);
+ GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight);
+ }
+
+ /* Determine the current screen size.
+ * This is NOT necessarily the size of the Framebuffer or GAPI, as they return
+ * the displaysize in ORIENTATION_UP */
+ this->info.current_w = GetSystemMetrics(SM_CXSCREEN);
+ this->info.current_h = GetSystemMetrics(SM_CYSCREEN);
+
+ /* Sort the mode lists */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( gapi->SDL_nummodes[i] > 0 ) {
+ SDL_qsort(gapi->SDL_modelist[i], gapi->SDL_nummodes[i], sizeof *gapi->SDL_modelist[i], cmpmodes);
+ }
+ }
+
+ vformat->BitsPerPixel = gapi->gxProperties.cBPP < 8 ? 16 : (unsigned char)gapi->gxProperties.cBPP;
+
+ // Get color mask
+ if (gapi->gxProperties.ffFormat & kfDirect565) {
+ vformat->BitsPerPixel = 16;
+ vformat->Rmask = 0x0000f800;
+ vformat->Gmask = 0x000007e0;
+ vformat->Bmask = 0x0000001f;
+ gapi->videoMode = GAPI_DIRECT_565;
+ }
+ else
+ if (gapi->gxProperties.ffFormat & kfDirect555) {
+ vformat->BitsPerPixel = 16;
+ vformat->Rmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Bmask = 0x0000001f;
+ gapi->videoMode = GAPI_DIRECT_555;
+ }
+ else
+ if ((gapi->gxProperties.ffFormat & kfDirect) && (gapi->gxProperties.cBPP < 8)) {
+ // We'll perform the conversion
+ vformat->BitsPerPixel = 16;
+ vformat->Rmask = 0x0000f800; // 16 bit 565
+ vformat->Gmask = 0x000007e0;
+ vformat->Bmask = 0x0000001f;
+ if (gapi->gxProperties.ffFormat & kfDirectInverted)
+ gapi->invert = (1 << gapi->gxProperties.cBPP) - 1;
+ gapi->colorscale = gapi->gxProperties.cBPP < 8 ? 8 - gapi->gxProperties.cBPP : 0;
+ gapi->videoMode = GAPI_MONO;
+ }
+ else
+ if (gapi->gxProperties.ffFormat & kfPalette) {
+ gapi->videoMode = GAPI_PALETTE;
+ }
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(gapi->SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+// return (SDL_Rect **) -1;
+}
+
+SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ SDL_Surface *video;
+ Uint32 Rmask, Gmask, Bmask;
+ DWORD style;
+ SDL_Rect allScreen;
+
+ if( bpp < 4 )
+ {
+ SDL_SetError("1 bpp and 2 bpp modes is not implemented yet!");
+ return 0;
+ }
+
+ /* Recalculate bitmasks if necessary */
+ if (bpp == current->format->BitsPerPixel) {
+ video = current;
+ }
+ else {
+ switch(bpp) {
+ case 8:
+ Rmask = 0;
+ Gmask = 0;
+ Bmask = 0;
+ break;
+ case 15:
+ case 16:
+ /* Default is 565 unless the display is specifically 555 */
+ if (gapi->gxProperties.ffFormat & kfDirect555) {
+ Rmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Bmask = 0x0000001f;
+ }
+ else {
+ Rmask = 0x0000f800;
+ Gmask = 0x000007e0;
+ Bmask = 0x0000001f;
+ }
+ break;
+ case 24:
+ case 32:
+ Rmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Bmask = 0x000000ff;
+ break;
+ default:
+ SDL_SetError("Unsupported Bits Per Pixel format requested");
+ return NULL;
+ }
+ video = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ 0, 0, bpp, Rmask, Gmask, Bmask, 0);
+ if ( video == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ }
+
+ gapi->userOrientation = SDL_ORIENTATION_UP;
+ gapi->systemOrientation = SDL_ORIENTATION_UP;
+ video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports fullscreen only */
+
+ /* GAPI or VGA? */
+ if( g_hGapiLib )
+ {
+ FillStructs(this, 0);
+ if( (((unsigned)width != gapi->gxProperties.cxWidth) || ((unsigned)height != gapi->gxProperties.cyHeight))
+ && (((unsigned)width != gapi->gxProperties.cyHeight) || ((unsigned)height != gapi->gxProperties.cxWidth)))
+ FillStructs(this, 1); // gapi is found but we use VGA resolution
+ } else
+ FillStructs(this, 1);
+
+ if ( !gapi->needUpdate && !gapi->videoMem) {
+ SDL_SetError("Couldn't get address of video memory, may be unsupported device or bug");
+ return(NULL);
+ }
+
+ /* detect user landscape mode */
+ if( (width > height) && (gapi->gxProperties.cxWidth < gapi->gxProperties.cyHeight))
+ gapi->userOrientation = SDL_ORIENTATION_RIGHT;
+
+ if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN))
+ gapi->systemOrientation = SDL_ORIENTATION_RIGHT;
+
+ gapi->hiresFix = 0;
+
+ /* check hires */
+ if(GetSystemMetrics(SM_CXSCREEN) < width && GetSystemMetrics(SM_CYSCREEN) < height)
+ {
+ gapi->hiresFix = 1;
+ }
+
+ switch( gapi->userOrientation )
+ {
+ case SDL_ORIENTATION_UP:
+ gapi->startOffset = 0;
+ gapi->dstLineStep = gapi->gxProperties.cbyPitch;
+ gapi->dstPixelStep = gapi->gxProperties.cbxPitch;
+ break;
+ case SDL_ORIENTATION_RIGHT:
+ switch( gapi->gapiOrientation )
+ {
+ case SDL_ORIENTATION_UP:
+ case SDL_ORIENTATION_RIGHT:
+ case SDL_ORIENTATION_LEFT:
+ if( (gapi->videoMode == GAPI_MONO) )
+ gapi->startOffset = -gapi->gxProperties.cbxPitch + 1; // monochrome mode
+ else
+ gapi->startOffset = gapi->gxProperties.cbyPitch * (gapi->gxProperties.cyHeight - 1);
+
+ gapi->dstLineStep = gapi->gxProperties.cbxPitch;
+ gapi->dstPixelStep = -gapi->gxProperties.cbyPitch;
+ break;
+ }
+ }
+
+ video->w = gapi->w = width;
+ video->h = gapi->h = height;
+ video->pitch = SDL_CalculatePitch(video);
+
+ /* Small fix for WinCE/Win32 - when activating window
+ SDL_VideoSurface is equal to zero, so activating code
+ is not called properly for fullscreen windows because
+ macros WINDIB_FULLSCREEN uses SDL_VideoSurface
+ */
+ SDL_VideoSurface = video;
+
+ /* GAPI is always fullscreen, title bar is useless */
+ style = 0;
+
+ if (!SDL_windowid)
+ SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+ /* Allocate bitmap */
+ if( gapi->buffer )
+ {
+ SDL_free( gapi->buffer );
+ gapi->buffer = NULL;
+ }
+ gapi->buffer = SDL_malloc(video->h * video->pitch);
+ video->pixels = gapi->buffer;
+
+ if ( ! gapi->buffer ) {
+ SDL_SetError("Couldn't allocate buffer for requested mode");
+ return(NULL);
+ }
+
+ SDL_memset(gapi->buffer, 255, video->h * video->pitch);
+ MoveWindow(SDL_Window, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE);
+ ShowWindow(SDL_Window, SW_SHOW);
+ SetForegroundWindow(SDL_Window);
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+
+ /* Open GAPI display */
+ if( !gapi->useVga && gapi->useGXOpenDisplay && !gapi->alreadyGXOpened )
+ {
+#if REPORT_VIDEO_INFO
+ printf("system display width (orig): %d\n", GetSystemMetrics(SM_CXSCREEN));
+ printf("system display height (orig): %d\n", GetSystemMetrics(SM_CYSCREEN));
+#endif
+ gapi->alreadyGXOpened = 1;
+ if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
+ {
+ SDL_SetError("Couldn't initialize GAPI");
+ return(NULL);
+ }
+ }
+
+ if(gapi->useVga)
+ gapi->coordinateTransform = (4 - gapi->systemOrientation + gapi->userOrientation) % 4;
+ else
+ gapi->coordinateTransform = gapi->userOrientation;
+
+#if REPORT_VIDEO_INFO
+ printf("Video properties:\n");
+ printf("display bpp: %d\n", gapi->gxProperties.cBPP);
+ printf("display width: %d\n", gapi->gxProperties.cxWidth);
+ printf("display height: %d\n", gapi->gxProperties.cyHeight);
+ printf("system display width: %d\n", GetSystemMetrics(SM_CXSCREEN));
+ printf("system display height: %d\n", GetSystemMetrics(SM_CYSCREEN));
+ printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
+ printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
+ printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);
+ printf("user orientation: %d\n", gapi->userOrientation);
+ printf("system orientation: %d\n", gapi->systemOrientation);
+ printf("gapi orientation: %d\n", gapi->gapiOrientation);
+
+
+ if( !gapi->useVga && gapi->useGXOpenDisplay && gapi->needUpdate)
+ {
+ gapi->videoMem = gapi->gxFunc.GXBeginDraw();
+ gapi->gxFunc.GXEndDraw();
+ }
+
+ printf("video memory: 0x%x\n", gapi->videoMem);
+ printf("need update: %d\n", gapi->needUpdate);
+ printf("hi-res fix: %d\n", gapi->hiresFix);
+ printf("VGA is available on the device: %d\n", g_bRawBufferAvailable);
+ printf("use raw framebuffer: %d\n", gapi->useVga);
+ printf("video surface bpp: %d\n", video->format->BitsPerPixel);
+ printf("video surface width: %d\n", video->w);
+ printf("video surface height: %d\n", video->h);
+ printf("mouse/arrows transformation angle: %d\n", gapi->coordinateTransform);
+#endif
+
+
+ /* Blank screen */
+ allScreen.x = allScreen.y = 0;
+ allScreen.w = video->w - 1;
+ allScreen.h = video->h - 1;
+ GAPI_UpdateRects(this, 1, &allScreen);
+
+ /* We're done */
+ return(video);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int updateLine8to8(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width, int height, int lines)
+{
+ if( gapi->dstPixelStep == 1) /* optimized blitting on most devices */
+ {
+ SDL_memcpy(destPointer, srcPointer, width);
+ return 1;
+ } else
+ {
+ // TODO: read 4 pixels, write DWORD
+ int step = gapi->dstPixelStep;
+ while(width--)
+ {
+ *destPointer = *srcPointer++;
+ destPointer += step;
+ }
+ }
+ return 1;
+}
+
+/* Video memory is very slow so lets optimize as much as possible */
+static int updateLine16to16(_THIS, PIXEL *srcPointer, PIXEL *destPointer, int width, int height, int lines)
+{
+ PIXEL *line1, *line2;
+ int step = gapi->dstPixelStep / 2;
+
+ if( step == 1 ) /* optimized blitting on most devices */
+ {
+ SDL_memcpy(destPointer, srcPointer, width * sizeof(PIXEL));
+ return 1;
+ }
+ else
+ {
+ if( (gapi->gapiOrientation != SDL_ORIENTATION_UP) &&
+ (gapi->userOrientation == SDL_ORIENTATION_UP )) // iPaq 3660/3800 and user orientation up
+ {
+ // to prevent data misalignment copy only one line
+ if( ((((unsigned)destPointer & 3) != 0) && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT))
+ || ((((unsigned)destPointer & 3) == 0) && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT))
+ || (lines == 1) )
+ {
+ while(width--)
+ {
+ *destPointer = *srcPointer++;
+ destPointer += step;
+ }
+ return 1;
+ }
+
+ /* read two lines at the same time, write DWORD */
+ line1 = srcPointer;
+ line2 = srcPointer + SDL_VideoSurface->pitch / 2;
+
+ if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT )
+ while(width--) // iPaq 3800
+ {
+ *(DWORD*)destPointer =(*line2++ << 16) | *line1++;
+ destPointer += step;
+ }
+ else
+ {
+ destPointer += gapi->gxProperties.cbyPitch / 2;
+
+ while(width--) // iPaq 3660
+ {
+ *(DWORD*)destPointer =(*line1++ << 16) | *line2++;
+ destPointer += step;
+ }
+ }
+ return 2;
+ } else
+ {
+ // iPaq 3800 and user orientation landscape
+ if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT )
+ {
+ int w1;
+
+ // to prevent data misalignment copy only one pixel
+ if( (((unsigned)destPointer & 3) == 0) && (width > 0))
+ {
+ *destPointer-- = *srcPointer++;
+ width--;
+ }
+
+ destPointer--;
+
+ w1 = width / 2;
+
+ while(w1--)
+ {
+ DWORD p = *(DWORD*)srcPointer;
+ *((DWORD*)destPointer) = (p << 16) | (p >> 16);
+ destPointer -= 2;
+ srcPointer += 2;
+ }
+
+ if( width & 1 ) // copy the last pixel
+ {
+ destPointer++;
+ *destPointer = *srcPointer;
+ }
+
+ return 1;
+ }
+
+ // modern iPaqs and user orientation landscape
+ // read two pixels, write DWORD
+
+ line1 = srcPointer;
+ line2 = srcPointer + SDL_VideoSurface->pitch / 2;
+
+ if( (((unsigned)destPointer & 3) != 0) || (lines == 1) )
+ {
+ while(width--)
+ {
+ *destPointer = *srcPointer++;
+ destPointer += step;
+ }
+ return 1;
+ }
+
+ while(width--)
+ {
+ *(DWORD*)destPointer =(*line2++ << 16) | *line1++;
+ destPointer -= gapi->gxProperties.cbyPitch / 2;
+ }
+ return 2;
+ }
+ }
+}
+
+// Color component masks for 565
+#define REDMASK (31<<11)
+#define GREENMASK (63<<5)
+#define BLUEMASK (31)
+
+
+static int updateLine16to4(_THIS, PIXEL *srcPointer, unsigned char *destPointer, int width, int height, int lines, int yNibble, int xNibble)
+{
+ PIXEL *line1, *line2;
+ int step = gapi->dstPixelStep;
+
+ if( gapi->userOrientation == SDL_ORIENTATION_UP )
+ {
+ if( yNibble ) // copy bottom half of a line
+ {
+ while(width--)
+ {
+ PIXEL c1 = *srcPointer++;
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
+ destPointer += step;
+ }
+ return 1;
+ }
+
+ // either 1 pixel picture or tail, anyway this is the last line
+ if( lines == 1 )
+ {
+ while(width--)
+ {
+ PIXEL c1 = *srcPointer++;
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
+ destPointer += step;
+ }
+ return 1;
+ }
+
+ line1 = srcPointer;
+ line2 = srcPointer + SDL_VideoSurface->pitch / 2;
+
+ while(width--)
+ {
+ PIXEL c1 = *line1++;
+ PIXEL c2 = *line2++;
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK);
+ *destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4));
+ destPointer += step;
+ }
+ return 2;
+ } else
+ {
+ int w1;
+ w1 = width / 2;
+
+ if( xNibble )
+ {
+ // copy one pixel
+ PIXEL c1 = *srcPointer++;
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
+ destPointer++;
+ }
+
+ while(w1--)
+ {
+ PIXEL c1 = *srcPointer;
+ PIXEL c2 = *(srcPointer + 1);
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK);
+ *destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4));
+ srcPointer += 2;
+ }
+
+ // copy tail
+ if( (width & 1) && !xNibble )
+ {
+ PIXEL c1 = *srcPointer;
+ c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
+ *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
+ }
+
+ return 1;
+ }
+}
+
+static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i, height;
+ int linesProcessed;
+ int xNibble, yNibble;
+
+ for (i=0; i<numrects; i++)
+ {
+ unsigned char *destPointer;
+ unsigned char *srcPointer;
+
+ if( gapi->userOrientation == SDL_ORIENTATION_UP )
+ destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset - rects[i].y * gapi->gxProperties.cBPP / 8 + rects[i].x * gapi->dstPixelStep;
+ else
+ destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].x * gapi->gxProperties.cBPP / 8 + rects[i].y * gapi->dstLineStep;
+
+ srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2;
+ yNibble = rects[i].y & 1; // TODO: only for 4 bpp
+ xNibble = rects[i].x & 1;
+ height = rects[i].h;
+ while (height > 0)
+ {
+ switch(gapi->gxProperties.cBPP)
+ {
+ case 2: // TODO
+ case 4:
+ linesProcessed = updateLine16to4(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height, yNibble, xNibble);
+ yNibble = 0;
+ }
+ height -= linesProcessed;
+ if( gapi->userOrientation == SDL_ORIENTATION_UP )
+ destPointer--; // always fill 1 byte
+ else destPointer += gapi->dstLineStep;
+ srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes
+ }
+ }
+}
+
+static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i, height;
+ int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8;
+ int linesProcessed;
+ for (i=0; i<numrects; i++) {
+ unsigned char *destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep;
+ unsigned char *srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel;
+ height = rects[i].h;
+
+// fprintf(stderr, "Starting rect %dx%d, dst=0x%x, w = %d, h = %d\n", rects[i].w, rects[i].h,destPointer,rects[i].w,rects[i].h);
+// fflush(stderr);
+ linesProcessed = height;
+
+ while (height > 0) {
+ switch(bytesPerPixel)
+ {
+ case 1:
+ linesProcessed = updateLine8to8(this, srcPointer, (unsigned char *) destPointer, rects[i].w, rects[i].h, height);
+ break;
+ case 2:
+#pragma warning(disable: 4133)
+ linesProcessed = updateLine16to16(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height);
+ break;
+ }
+ height -= linesProcessed;
+ destPointer += gapi->dstLineStep * linesProcessed;
+ srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes
+ }
+// fprintf(stderr, "End of rect\n");
+// fflush(stderr);
+ }
+}
+
+
+static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ // we do not want to corrupt video memory
+ if( gapi->suspended ) return;
+
+ if( gapi->needUpdate )
+ gapi->videoMem = gapi->gxFunc.GXBeginDraw();
+
+ if( gapi->gxProperties.cBPP < 8 )
+ GAPI_UpdateRectsMono(this, numrects, rects);
+ else
+ GAPI_UpdateRectsColor(this, numrects, rects);
+
+ if( gapi->needUpdate )
+ gapi->gxFunc.GXEndDraw();
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void GAPI_VideoQuit(_THIS)
+{
+ int i, j;
+ /* Destroy the window and everything associated with it */
+ if ( SDL_Window )
+ {
+ if ((g_hGapiLib != 0) && this && gapi && gapi->gxFunc.GXCloseDisplay && !gapi->useVga)
+ gapi->gxFunc.GXCloseDisplay();
+
+ if (this->screen->pixels != NULL)
+ {
+ SDL_free(this->screen->pixels);
+ this->screen->pixels = NULL;
+ }
+ if ( screen_icn ) {
+ DestroyIcon(screen_icn);
+ screen_icn = NULL;
+ }
+
+ DIB_DestroyWindow(this);
+ SDL_UnregisterApp();
+
+ SDL_Window = NULL;
+#if defined(_WIN32_WCE)
+
+// Unload wince aygshell library to prevent leak
+ if( aygshell )
+ {
+ FreeLibrary(aygshell);
+ aygshell = NULL;
+ }
+#endif
+
+ /* Free video mode lists */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( gapi->SDL_modelist[i] != NULL ) {
+ for ( j=0; gapi->SDL_modelist[i][j]; ++j )
+ SDL_free(gapi->SDL_modelist[i][j]);
+ SDL_free(gapi->SDL_modelist[i]);
+ gapi->SDL_modelist[i] = NULL;
+ }
+ }
+
+ }
+
+}
+
+static void GAPI_Activate(_THIS, BOOL active, BOOL minimized)
+{
+ //Nothing to do here (as far as I know)
+}
+
+static void GAPI_RealizePalette(_THIS)
+{
+ OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
+}
+
+static void GAPI_PaletteChanged(_THIS, HWND window)
+{
+ OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
+}
+
+static void GAPI_WinPAINT(_THIS, HDC hdc)
+{
+ // draw current offscreen buffer on hdc
+
+ int bpp = 16; // we always use either 8 or 16 bpp internally
+ HGDIOBJ prevObject;
+ unsigned short *bitmapData;
+ HBITMAP hb;
+ HDC srcDC;
+
+ // Create a DIB
+ BYTE buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)] = {0};
+ BITMAPINFO* pBMI = (BITMAPINFO*)buffer;
+ BITMAPINFOHEADER* pHeader = &pBMI->bmiHeader;
+ DWORD* pColors = (DWORD*)&pBMI->bmiColors;
+
+ // CreateDIBSection does not support 332 pixel format on wce
+ if( gapi->gxProperties.cBPP == 8 ) return;
+
+ // DIB Header
+ pHeader->biSize = sizeof(BITMAPINFOHEADER);
+ pHeader->biWidth = gapi->w;
+ pHeader->biHeight = -gapi->h;
+ pHeader->biPlanes = 1;
+ pHeader->biBitCount = bpp;
+ pHeader->biCompression = BI_RGB;
+ pHeader->biSizeImage = (gapi->w * gapi->h * bpp) / 8;
+
+ // Color masks
+ if( bpp == 16 )
+ {
+ pColors[0] = REDMASK;
+ pColors[1] = GREENMASK;
+ pColors[2] = BLUEMASK;
+ pHeader->biCompression = BI_BITFIELDS;
+ }
+ // Create the DIB
+ hb = CreateDIBSection( 0, pBMI, DIB_RGB_COLORS, (void**)&bitmapData, 0, 0 );
+
+ // copy data
+ // FIXME: prevent misalignment, but I've never seen non aligned width of screen
+ memcpy(bitmapData, gapi->buffer, pHeader->biSizeImage);
+ srcDC = CreateCompatibleDC(hdc);
+ prevObject = SelectObject(srcDC, hb);
+
+ BitBlt(hdc, 0, 0, gapi->w, gapi->h, srcDC, 0, 0, SRCCOPY);
+
+ SelectObject(srcDC, prevObject);
+ DeleteObject(hb);
+ DeleteDC(srcDC);
+}
+
+int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ GAPI_CreatePalette(ncolors, colors);
+ return 1;
+}
diff --git a/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.h b/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.h
new file mode 100644
index 0000000..842d098
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gapi/SDL_gapivideo.h
@@ -0,0 +1,160 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_gapivideo_h
+#define _SDL_gapivideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+#include "../windib/SDL_gapidibvideo.h"
+
+/* From gx.h, since it's not really C compliant */
+
+struct GXDisplayProperties {
+ DWORD cxWidth;
+ DWORD cyHeight; // notice lack of 'th' in the word height.
+ long cbxPitch; // number of bytes to move right one x pixel - can be negative.
+ long cbyPitch; // number of bytes to move down one y pixel - can be negative.
+ long cBPP; // # of bits in each pixel
+ DWORD ffFormat; // format flags.
+};
+
+struct GXKeyList {
+ short vkUp; // key for up
+ POINT ptUp; // x,y position of key/button. Not on screen but in screen coordinates.
+ short vkDown;
+ POINT ptDown;
+ short vkLeft;
+ POINT ptLeft;
+ short vkRight;
+ POINT ptRight;
+ short vkA;
+ POINT ptA;
+ short vkB;
+ POINT ptB;
+ short vkC;
+ POINT ptC;
+ short vkStart;
+ POINT ptStart;
+};
+
+typedef int (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags);
+typedef int (*PFNGXCloseDisplay)();
+typedef void* (*PFNGXBeginDraw)();
+typedef int (*PFNGXEndDraw)();
+typedef int (*PFNGXOpenInput)();
+typedef int (*PFNGXCloseInput)();
+typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)();
+typedef struct GXKeyList (*PFNGXGetDefaultKeys)(int iOptions);
+typedef int (*PFNGXSuspend)();
+typedef int (*PFNGXResume)();
+typedef int (*PFNGXSetViewport)( DWORD dwTop, DWORD dwHeight, DWORD dwReserved1, DWORD dwReserved2 );
+typedef BOOL (*PFNGXIsDisplayDRAMBuffer)();
+
+struct GapiFunc
+{
+ PFNGXOpenDisplay GXOpenDisplay;
+ PFNGXCloseDisplay GXCloseDisplay;
+ PFNGXBeginDraw GXBeginDraw;
+ PFNGXEndDraw GXEndDraw;
+ PFNGXOpenInput GXOpenInput;
+ PFNGXCloseInput GXCloseInput;
+ PFNGXGetDisplayProperties GXGetDisplayProperties;
+ PFNGXGetDefaultKeys GXGetDefaultKeys;
+ PFNGXSuspend GXSuspend;
+ PFNGXResume GXResume;
+ PFNGXSetViewport GXSetViewport;
+ PFNGXIsDisplayDRAMBuffer GXIsDisplayDRAMBuffer;
+};
+
+#define kfLandscape 0x8 // Screen is rotated 270 degrees
+#define kfPalette 0x10 // Pixel values are indexes into a palette
+#define kfDirect 0x20 // Pixel values contain actual level information
+#define kfDirect555 0x40 // 5 bits each for red, green and blue values in a pixel.
+#define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel
+#define kfDirect888 0x100 // 8 bits each for red, green and blue values in a pixel.
+#define kfDirect444 0x200 // 4 red, 4 green, 4 blue
+#define kfDirectInverted 0x400
+
+#define GX_FULLSCREEN 0x01 // for OpenDisplay()
+#define GX_NORMALKEYS 0x02
+#define GX_LANDSCAPEKEYS 0x03
+
+
+/* GAPI video mode */
+typedef enum {
+ GAPI_NONE = 0,
+ GAPI_DIRECT_565,
+ GAPI_DIRECT_555,
+ GAPI_MONO,
+ GAPI_PALETTE
+} GAPIVideoMode;
+
+typedef unsigned short PIXEL;
+
+/* Private display data
+ begin with DIB private structure to allow DIB events code sharing
+*/
+struct GapiInfo {
+ /* Rotation which has to be applied to the key (arrow keys) and mouse events measured in quarters of a circle
+ * counter clockwise */
+ int coordinateTransform;
+ char hiresFix; /* using hires mode without defining hires resource */
+ int invert; //TODO this is only written but never read, so it should be removed
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+
+ // The orientation of the video mode user wants to get
+ // Probably restricted to UP and RIGHT
+ SDL_ScreenOrientation userOrientation;
+ SDL_ScreenOrientation systemOrientation;
+// --------------
+ int useGXOpenDisplay; /* use GXOpenDispplay */
+ int alreadyGXOpened;
+ int w, h;
+ // The orientation of GAPI framebuffer.
+ // Never changes on the same device.
+ SDL_ScreenOrientation gapiOrientation;
+
+ void *buffer; // may be 8, 16, 24, 32 bpp
+ PIXEL *videoMem;
+ BOOL needUpdate;
+ struct GXKeyList keyList;
+ struct GapiFunc gxFunc;
+ struct GXDisplayProperties gxProperties;
+ GAPIVideoMode videoMode;
+ int colorscale;
+ int dstLineStep; // in bytes
+ int dstPixelStep; // in bytes
+ int startOffset; // in bytes
+ int useVga;
+ int suspended; // do not pu anything into video memory
+};
+
+
+
+#endif /* _SDL_gapivideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents.c b/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents.c
new file mode 100644
index 0000000..c5a505d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents.c
@@ -0,0 +1,375 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * GEM SDL video driver implementation
+ * inspired from the Dummy SDL driver
+ *
+ * Patrice Mandin
+ * and work from
+ * Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
+ */
+
+#include <gem.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_gemvideo.h"
+#include "SDL_gemevents_c.h"
+#include "SDL_gemmouse_c.h"
+#include "../ataricommon/SDL_atarikeys.h" /* for keyboard scancodes */
+#include "../ataricommon/SDL_atarievents_c.h"
+#include "../ataricommon/SDL_xbiosevents_c.h"
+#include "../ataricommon/SDL_ataridevmouse_c.h"
+
+/* Variables */
+
+static unsigned char gem_currentkeyboard[ATARIBIOS_MAXKEYS];
+static unsigned char gem_previouskeyboard[ATARIBIOS_MAXKEYS];
+
+/* Functions prototypes */
+
+static int do_messages(_THIS, short *message);
+static void do_keyboard(short kc, short ks);
+static void do_mouse(_THIS, short mx, short my, short mb, short ks);
+
+/* Functions */
+
+void GEM_InitOSKeymap(_THIS)
+{
+ SDL_memset(gem_currentkeyboard, 0, sizeof(gem_currentkeyboard));
+ SDL_memset(gem_previouskeyboard, 0, sizeof(gem_previouskeyboard));
+
+ /* Mouse init */
+ GEM_mouse_relative = SDL_FALSE;
+
+ SDL_Atari_InitInternalKeymap(this);
+}
+
+void GEM_PumpEvents(_THIS)
+{
+ short prevkc, prevks;
+ static short maskmouseb=0;
+ int i;
+ SDL_keysym keysym;
+
+ SDL_memset(gem_currentkeyboard,0,sizeof(gem_currentkeyboard));
+ prevkc = prevks = 0;
+
+ for (;;)
+ {
+ int quit, resultat, event_mask, mouse_event;
+ short buffer[8], kc;
+ short x2,y2,w2,h2;
+ short mousex, mousey, mouseb, dummy;
+ short kstate;
+
+ quit =
+ mouse_event =
+ x2=y2=w2=h2 = 0;
+
+ event_mask = MU_MESAG|MU_TIMER|MU_KEYBD|MU_BUTTON;
+ if (!GEM_fullscreen && (GEM_handle>=0)) {
+ wind_get (GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2);
+ event_mask |= MU_M1;
+ mouse_event = ( (SDL_GetAppState() & SDL_APPMOUSEFOCUS)
+ == SDL_APPMOUSEFOCUS) ? MO_LEAVE : MO_ENTER;
+ }
+
+ resultat = evnt_multi(
+ event_mask,
+ 0x101,7,maskmouseb,
+ mouse_event,x2,y2,w2,h2,
+ 0,0,0,0,0,
+ buffer,
+ 10,
+ &mousex,&mousey,&mouseb,&kstate,&kc,&dummy
+ );
+
+ /* Message event ? */
+ if (resultat & MU_MESAG)
+ quit = do_messages(this, buffer);
+
+ /* Keyboard event ? */
+ if (resultat & MU_KEYBD) {
+ if ((prevkc != kc) || (prevks != kstate)) {
+ do_keyboard(kc,kstate);
+ } else {
+ /* Avoid looping, if repeating same key */
+ break;
+ }
+ }
+
+ /* Mouse entering/leaving window */
+ if (resultat & MU_M1) {
+ if (this->input_grab == SDL_GRAB_OFF) {
+ /* Switch mouse focus state */
+ SDL_PrivateAppActive((mouse_event == MO_ENTER),
+ SDL_APPMOUSEFOCUS);
+ }
+ GEM_CheckMouseMode(this);
+ }
+
+ /* Mouse button event ? */
+ if (resultat & MU_BUTTON) {
+ do_mouse(this, mousex, mousey, mouseb, kstate);
+ maskmouseb = mouseb & 7;
+ }
+
+ /* Timer event ? */
+ if ((resultat & MU_TIMER) || quit)
+ break;
+ }
+
+ /* Now generate keyboard events */
+ for (i=0; i<ATARIBIOS_MAXKEYS; i++) {
+ /* Key pressed ? */
+ if (gem_currentkeyboard[i] && !gem_previouskeyboard[i])
+ SDL_PrivateKeyboard(SDL_PRESSED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE));
+
+ /* Key unpressed ? */
+ if (gem_previouskeyboard[i] && !gem_currentkeyboard[i])
+ SDL_PrivateKeyboard(SDL_RELEASED,
+ SDL_Atari_TranslateKey(i, &keysym, SDL_FALSE));
+ }
+
+ SDL_memcpy(gem_previouskeyboard,gem_currentkeyboard,sizeof(gem_previouskeyboard));
+
+ /* Refresh window name ? */
+ if (GEM_refresh_name) {
+ const char *window_name =
+ (SDL_GetAppState() & SDL_APPACTIVE)
+ ? GEM_title_name : GEM_icon_name;
+ if (window_name) {
+ wind_set(GEM_handle,WF_NAME,
+ (short)(((unsigned long)window_name)>>16),
+ (short)(((unsigned long)window_name) & 0xffff),
+ 0,0);
+ }
+ GEM_refresh_name = SDL_FALSE;
+ }
+}
+
+static int do_messages(_THIS, short *message)
+{
+ int quit, check_mouse_mode;
+ short x2,y2,w2,h2;
+
+ quit = check_mouse_mode = 0;
+ switch (message[0]) {
+ case WM_CLOSED:
+ case AP_TERM:
+ SDL_PrivateQuit();
+ quit=1;
+ break;
+ case WM_MOVED:
+ wind_set(message[3],WF_CURRXYWH,message[4],message[5],message[6],message[7]);
+ break;
+ case WM_TOPPED:
+ wind_set(message[3],WF_TOP,message[4],0,0,0);
+ /* Continue with TOP event processing */
+ case WM_ONTOP:
+ SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+ if (VDI_setpalette) {
+ VDI_setpalette(this, VDI_curpalette);
+ }
+ check_mouse_mode = 1;
+ break;
+ case WM_REDRAW:
+ if (!GEM_lock_redraw) {
+ GEM_wind_redraw(this, message[3],&message[4]);
+ }
+ break;
+ case WM_ICONIFY:
+ case WM_ALLICONIFY:
+ wind_set(message[3],WF_ICONIFY,message[4],message[5],message[6],message[7]);
+ /* If we're active, make ourselves inactive */
+ if ( SDL_GetAppState() & SDL_APPACTIVE ) {
+ /* Send an internal deactivate event */
+ SDL_PrivateAppActive(0, SDL_APPACTIVE);
+ }
+ /* Update window title */
+ if (GEM_refresh_name && GEM_icon_name) {
+ wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_icon_name)>>16),(short)(((unsigned long)GEM_icon_name) & 0xffff),0,0);
+ GEM_refresh_name = SDL_FALSE;
+ }
+ check_mouse_mode = 1;
+ break;
+ case WM_UNICONIFY:
+ wind_set(message[3],WF_UNICONIFY,message[4],message[5],message[6],message[7]);
+ /* If we're not active, make ourselves active */
+ if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) {
+ /* Send an internal activate event */
+ SDL_PrivateAppActive(1, SDL_APPACTIVE);
+ }
+ if (GEM_refresh_name && GEM_title_name) {
+ wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
+ GEM_refresh_name = SDL_FALSE;
+ }
+ check_mouse_mode = 1;
+ break;
+ case WM_SIZED:
+ wind_set (message[3], WF_CURRXYWH, message[4], message[5], message[6], message[7]);
+ wind_get (message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
+ GEM_win_fulled = SDL_FALSE; /* Cancel maximized flag */
+ GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */
+ SDL_PrivateResize(w2, h2);
+ break;
+ case WM_FULLED:
+ {
+ short x,y,w,h;
+
+ if (GEM_win_fulled) {
+ wind_get (message[3], WF_PREVXYWH, &x, &y, &w, &h);
+ GEM_win_fulled = SDL_FALSE;
+ } else {
+ x = GEM_desk_x;
+ y = GEM_desk_y;
+ w = GEM_desk_w;
+ h = GEM_desk_h;
+ GEM_win_fulled = SDL_TRUE;
+ }
+ wind_set (message[3], WF_CURRXYWH, x, y, w, h);
+ wind_get (message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
+ GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */
+ SDL_PrivateResize(w2, h2);
+ }
+ break;
+ case WM_BOTTOMED:
+ wind_set(message[3],WF_BOTTOM,0,0,0,0);
+ /* Continue with BOTTOM event processing */
+ case WM_UNTOPPED:
+ SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+ if (VDI_setpalette) {
+ VDI_setpalette(this, VDI_oldpalette);
+ }
+ check_mouse_mode = 1;
+ break;
+ }
+
+ if (check_mouse_mode) {
+ GEM_CheckMouseMode(this);
+ }
+
+ return quit;
+}
+
+static void do_keyboard(short kc, short ks)
+{
+ int scancode;
+
+ if (kc) {
+ scancode=(kc>>8) & (ATARIBIOS_MAXKEYS-1);
+ gem_currentkeyboard[scancode]=0xFF;
+ }
+
+ /* Read special keys */
+ if (ks & K_RSHIFT)
+ gem_currentkeyboard[SCANCODE_RIGHTSHIFT]=0xFF;
+ if (ks & K_LSHIFT)
+ gem_currentkeyboard[SCANCODE_LEFTSHIFT]=0xFF;
+ if (ks & K_CTRL)
+ gem_currentkeyboard[SCANCODE_LEFTCONTROL]=0xFF;
+ if (ks & K_ALT)
+ gem_currentkeyboard[SCANCODE_LEFTALT]=0xFF;
+}
+
+static void do_mouse(_THIS, short mx, short my, short mb, short ks)
+{
+ static short prevmousex=0, prevmousey=0, prevmouseb=0;
+ short x2, y2, w2, h2;
+
+ /* Don't return mouse events if out of window */
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS)==0) {
+ return;
+ }
+
+ /* Retrieve window coords, and generate mouse events accordingly */
+ x2 = y2 = 0;
+ w2 = VDI_w;
+ h2 = VDI_h;
+ if ((!GEM_fullscreen) && (GEM_handle>=0)) {
+ wind_get (GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2);
+
+ /* Do not generate mouse button event if out of window working area */
+ if ((mx<x2) || (mx>=x2+w2) || (my<y2) || (my>=y2+h2)) {
+ mb=prevmouseb;
+ }
+ }
+
+ /* Mouse motion ? */
+ if (GEM_mouse_relative) {
+ if (GEM_usedevmouse) {
+ SDL_AtariDevMouse_PostMouseEvents(this, SDL_FALSE);
+ } else {
+ SDL_AtariXbios_PostMouseEvents(this, SDL_FALSE);
+ }
+ } else {
+ if ((prevmousex!=mx) || (prevmousey!=my)) {
+ int posx, posy;
+
+ /* Give mouse position relative to window position */
+ posx = mx - x2;
+ if (posx<0) posx = 0;
+ if (posx>w2) posx = w2-1;
+ posy = my - y2;
+ if (posy<0) posy = 0;
+ if (posy>h2) posy = h2-1;
+
+ SDL_PrivateMouseMotion(0, 0, posx, posy);
+ }
+ prevmousex = mx;
+ prevmousey = my;
+ }
+
+ /* Mouse button ? */
+ if (prevmouseb!=mb) {
+ int i;
+
+ for (i=0;i<3;i++) {
+ int curbutton, prevbutton;
+
+ curbutton = mb & (1<<i);
+ prevbutton = prevmouseb & (1<<i);
+
+ if (curbutton && !prevbutton) {
+ SDL_PrivateMouseButton(SDL_PRESSED, i+1, 0, 0);
+ }
+ if (!curbutton && prevbutton) {
+ SDL_PrivateMouseButton(SDL_RELEASED, i+1, 0, 0);
+ }
+ }
+ prevmouseb = mb;
+ }
+
+ /* Read special keys */
+ if (ks & K_RSHIFT)
+ gem_currentkeyboard[SCANCODE_RIGHTSHIFT]=0xFF;
+ if (ks & K_LSHIFT)
+ gem_currentkeyboard[SCANCODE_LEFTSHIFT]=0xFF;
+ if (ks & K_CTRL)
+ gem_currentkeyboard[SCANCODE_LEFTCONTROL]=0xFF;
+ if (ks & K_ALT)
+ gem_currentkeyboard[SCANCODE_LEFTALT]=0xFF;
+}
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents_c.h b/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents_c.h
new file mode 100644
index 0000000..7d5d9b3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemevents_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_gemvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c) */
+
+extern void GEM_InitOSKeymap(_THIS);
+extern void GEM_PumpEvents(_THIS);
+
+/* end of SDL_gemevents_c.h */
+
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse.c b/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse.c
new file mode 100644
index 0000000..c876cff
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse.c
@@ -0,0 +1,205 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * GEM Mouse manager
+ *
+ * Patrice Mandin
+ */
+
+#include <gem.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_gemmouse_c.h"
+#include "SDL_gemvideo.h"
+#include "../ataricommon/SDL_xbiosevents_c.h"
+
+/* Defines */
+
+/*#define DEBUG_VIDEO_GEM 1*/
+
+#define MAXCURWIDTH 16
+#define MAXCURHEIGHT 16
+
+void GEM_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: free cursor\n");
+#endif
+
+ if (cursor == NULL)
+ return;
+
+ graf_mouse(ARROW, NULL);
+
+ if (cursor->mform_p != NULL)
+ SDL_free(cursor->mform_p);
+
+ SDL_free(cursor);
+}
+
+WMcursor *GEM_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ MFORM *new_mform;
+ int i;
+
+#ifdef DEBUG_VIDEO_GEM
+ Uint16 *data1, *mask1;
+
+ printf("sdl:video:gem: create cursor\n");
+#endif
+
+ /* Check the size */
+ if ( (w > MAXCURWIDTH) || (h > MAXCURHEIGHT) ) {
+ SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
+ MAXCURWIDTH, MAXCURHEIGHT);
+ return(NULL);
+ }
+
+ /* Allocate the cursor memory */
+ cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
+ if ( cursor == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ /* Allocate mform */
+ new_mform = (MFORM *)SDL_malloc(sizeof(MFORM));
+ if (new_mform == NULL) {
+ SDL_free(cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ cursor->mform_p = new_mform;
+
+ new_mform->mf_xhot = hot_x;
+ new_mform->mf_yhot = hot_y;
+ new_mform->mf_nplanes = 1;
+ new_mform->mf_fg = 0;
+ new_mform->mf_bg = 1;
+
+ for (i=0;i<MAXCURHEIGHT;i++) {
+ new_mform->mf_mask[i]=0;
+ new_mform->mf_data[i]=0;
+#ifdef DEBUG_VIDEO_GEM
+ data1 = (Uint16 *) &data[i<<1];
+ mask1 = (Uint16 *) &mask[i<<1];
+ printf("sdl:video:gem: source: line %d: data=0x%04x, mask=0x%04x\n",
+ i, data1[i], mask1[i]);
+#endif
+ }
+
+ if (w<=8) {
+ for (i=0;i<h;i++) {
+ new_mform->mf_mask[i]= mask[i]<<8;
+ new_mform->mf_data[i]= data[i]<<8;
+ }
+ } else {
+ for (i=0;i<h;i++) {
+ new_mform->mf_mask[i]= (mask[i<<1]<<8) | mask[(i<<1)+1];
+ new_mform->mf_data[i]= (data[i<<1]<<8) | data[(i<<1)+1];
+ }
+ }
+
+#ifdef DEBUG_VIDEO_GEM
+ for (i=0; i<h ;i++) {
+ printf("sdl:video:gem: cursor: line %d: data=0x%04x, mask=0x%04x\n",
+ i, new_mform->mf_data[i], new_mform->mf_mask[i]);
+ }
+
+ printf("sdl:video:gem: CreateWMCursor(): done\n");
+#endif
+
+ return cursor;
+}
+
+int GEM_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ GEM_cursor = cursor;
+
+ GEM_CheckMouseMode(this);
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: ShowWMCursor(0x%08x)\n", (long) cursor);
+#endif
+
+ return 1;
+}
+
+#if 0
+void GEM_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ /* This seems to work only on AES 3.4 (Falcon) */
+
+ EVNTREC warpevent;
+
+ warpevent.ap_event = APPEVNT_MOUSE;
+ warpevent.ap_value = (x << 16) | y;
+
+ appl_tplay(&warpevent, 1, 1000);
+}
+#endif
+
+void GEM_CheckMouseMode(_THIS)
+{
+ const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+ int set_system_cursor = 1, show_system_cursor = 1;
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: check mouse mode\n");
+#endif
+
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ GEM_mouse_relative = (!(SDL_cursorstate & CURSOR_VISIBLE))
+ && (this->input_grab != SDL_GRAB_OFF)
+ && (SDL_GetAppState() & SDL_APPACTIVE);
+ SDL_AtariXbios_LockMousePosition(GEM_mouse_relative);
+
+ if (SDL_cursorstate & CURSOR_VISIBLE) {
+ /* Application defined cursor only over the application window */
+ if ((SDL_GetAppState() & full_focus) == full_focus) {
+ if (GEM_cursor) {
+ graf_mouse(USER_DEF, GEM_cursor->mform_p);
+ set_system_cursor = 0;
+ } else {
+ show_system_cursor = 0;
+ }
+ }
+ } else {
+ /* Mouse cursor hidden only over the application window */
+ if ((SDL_GetAppState() & full_focus) == full_focus) {
+ set_system_cursor = 0;
+ show_system_cursor = 0;
+ }
+ }
+
+ graf_mouse(show_system_cursor ? M_ON : M_OFF, NULL);
+ if (set_system_cursor) {
+ graf_mouse(ARROW, NULL);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse_c.h b/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse_c.h
new file mode 100644
index 0000000..06f90ba
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemmouse_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_gemvideo.h"
+
+/* Functions to be exported */
+extern void GEM_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *GEM_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int GEM_ShowWMCursor(_THIS, WMcursor *cursor);
+#if 0
+extern void GEM_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+#endif
+extern void GEM_CheckMouseMode(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.c b/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.c
new file mode 100644
index 0000000..2ce9151
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.c
@@ -0,0 +1,1337 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ GEM video driver
+
+ Patrice Mandin
+ and work from
+ Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
+*/
+
+/* Mint includes */
+#include <gem.h>
+#include <gemx.h>
+#include <mint/osbind.h>
+#include <mint/cookie.h>
+
+#include "SDL_endian.h"
+#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_cursor_c.h"
+
+#include "../ataricommon/SDL_ataric2p_s.h"
+#include "../ataricommon/SDL_atarieddi_s.h"
+#include "../ataricommon/SDL_atarimxalloc_c.h"
+#include "../ataricommon/SDL_atarigl_c.h"
+
+#include "SDL_gemvideo.h"
+#include "SDL_gemevents_c.h"
+#include "SDL_gemmouse_c.h"
+#include "SDL_gemwm_c.h"
+#include "../ataricommon/SDL_xbiosevents_c.h"
+#include "../ataricommon/SDL_ataridevmouse_c.h"
+
+/* Defines */
+
+/*#define DEBUG_VIDEO_GEM 1*/
+
+#define GEM_VID_DRIVER_NAME "gem"
+
+#undef MIN
+#define MIN(a,b) (((a)<(b)) ? (a) : (b))
+#undef MAX
+#define MAX(a,b) (((a)>(b)) ? (a) : (b))
+
+/* Variables */
+
+static unsigned char vdi_index[256] = {
+ 0, 2, 3, 6, 4, 7, 5, 8,
+ 9, 10, 11, 14, 12, 15, 13, 255
+};
+
+static const char empty_name[]="";
+
+/* Initialization/Query functions */
+static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GEM_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
+static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
+static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+#if 0
+static int GEM_ToggleFullScreen(_THIS, int on);
+#endif
+
+/* Internal functions */
+static void GEM_FreeBuffers(_THIS);
+static void GEM_ClearScreen(_THIS);
+static void GEM_ClearRect(_THIS, short *rect);
+static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
+static void GEM_LockScreen(_THIS);
+static void GEM_UnlockScreen(_THIS);
+static void refresh_window(_THIS, int winhandle, short *rect);
+
+#if SDL_VIDEO_OPENGL
+/* OpenGL functions */
+static void GEM_GL_SwapBuffers(_THIS);
+#endif
+
+/* GEM driver bootstrap functions */
+
+static int GEM_Available(void)
+{
+ /* Test if AES available */
+ if (appl_init() == -1)
+ return 0;
+
+ appl_exit();
+ return 1;
+}
+
+static void GEM_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *GEM_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+ int vectors_mask;
+/* unsigned long dummy;*/
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ device->gl_data = (struct SDL_PrivateGLData *)
+ SDL_malloc((sizeof *device->gl_data));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
+
+ /* Set the function pointers */
+ device->VideoInit = GEM_VideoInit;
+ device->ListModes = GEM_ListModes;
+ device->SetVideoMode = GEM_SetVideoMode;
+ device->SetColors = GEM_SetColors;
+ device->UpdateRects = NULL /*GEM_UpdateRects*/;
+ device->VideoQuit = GEM_VideoQuit;
+ device->AllocHWSurface = GEM_AllocHWSurface;
+ device->LockHWSurface = GEM_LockHWSurface;
+ device->UnlockHWSurface = GEM_UnlockHWSurface;
+ device->FlipHWSurface = GEM_FlipHWSurface;
+ device->FreeHWSurface = GEM_FreeHWSurface;
+ device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen*/;
+
+ /* Window manager */
+ device->SetCaption = GEM_SetCaption;
+ device->SetIcon = GEM_SetIcon;
+ device->IconifyWindow = GEM_IconifyWindow;
+ device->GrabInput = GEM_GrabInput;
+
+ /* Events */
+ device->InitOSKeymap = GEM_InitOSKeymap;
+ device->PumpEvents = GEM_PumpEvents;
+
+ /* Mouse */
+ device->FreeWMCursor = GEM_FreeWMCursor;
+ device->CreateWMCursor = GEM_CreateWMCursor;
+ device->ShowWMCursor = GEM_ShowWMCursor;
+ device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
+ device->CheckMouseMode = GEM_CheckMouseMode;
+
+#if SDL_VIDEO_OPENGL
+ /* OpenGL functions */
+ device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
+ device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
+ device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
+ device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
+ device->GL_SwapBuffers = GEM_GL_SwapBuffers;
+#endif
+
+ device->hidden->use_dev_mouse =
+ (SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
+
+ vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS; /* XBIOS joystick events */
+ if (!(device->hidden->use_dev_mouse)) {
+ vectors_mask |= ATARI_XBIOS_MOUSEEVENTS; /* XBIOS mouse events */
+ }
+/* if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
+ vectors_mask = 0;
+ }*/
+
+ SDL_AtariXbios_InstallVectors(vectors_mask);
+
+ device->free = GEM_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap GEM_bootstrap = {
+ GEM_VID_DRIVER_NAME, "Atari GEM video driver",
+ GEM_Available, GEM_CreateDevice
+};
+
+static void VDI_ReadExtInfo(_THIS, short *work_out)
+{
+ unsigned long EdDI_version;
+ long cookie_EdDI;
+ Uint16 clut_type;
+
+ /* Read EdDI informations */
+ if (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) {
+ return;
+ }
+
+ EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
+
+ vq_scrninfo(VDI_handle, work_out);
+
+ VDI_format = work_out[0];
+ clut_type = work_out[1];
+
+ /* With EdDI>=1.1, we can have screen pitch, address and format
+ * so we can directly write to screen without using vro_cpyfm
+ */
+ if (EdDI_version >= EDDI_11) {
+ VDI_pitch = work_out[5];
+ VDI_screen = (void *) *((unsigned long *) &work_out[6]);
+ }
+
+ switch(clut_type) {
+ case VDI_CLUT_HARDWARE:
+ {
+ int i;
+ Uint16 *tmp_p;
+
+ tmp_p = (Uint16 *)&work_out[16];
+
+ for (i=0;i<256;i++) {
+ vdi_index[*tmp_p++] = i;
+ }
+ }
+ break;
+ case VDI_CLUT_SOFTWARE:
+ {
+ int component; /* red, green, blue, alpha, overlay */
+ int num_bit;
+ unsigned short *tmp_p;
+
+ /* We can build masks with info here */
+ tmp_p = (unsigned short *) &work_out[16];
+ for (component=0;component<5;component++) {
+ for (num_bit=0;num_bit<16;num_bit++) {
+ unsigned short valeur;
+
+ valeur = *tmp_p++;
+
+ if (valeur == 0xffff) {
+ continue;
+ }
+
+ switch(component) {
+ case 0:
+ VDI_redmask |= 1<< valeur;
+ break;
+ case 1:
+ VDI_greenmask |= 1<< valeur;
+ break;
+ case 2:
+ VDI_bluemask |= 1<< valeur;
+ break;
+ case 3:
+ VDI_alphamask |= 1<< valeur;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Remove lower green bits for Intel endian screen */
+ if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
+ VDI_greenmask &= ~(7<<13);
+ }
+ break;
+ case VDI_CLUT_NONE:
+ break;
+ }
+}
+
+int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i, menubar_size;
+ short work_in[12], work_out[272], dummy;
+
+ /* Open AES (Application Environment Services) */
+ if (appl_init() == -1) {
+ fprintf(stderr,"Can not open AES\n");
+ return 1;
+ }
+
+ /* Read version and features */
+ GEM_version = aes_global[0];
+ if (GEM_version >= 0x0410) {
+ short ap_gout[4], errorcode;
+
+ GEM_wfeatures=0;
+ errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
+
+ if (errorcode==0) {
+ GEM_wfeatures=ap_gout[0];
+ }
+ }
+
+ /* Ask VDI physical workstation handle opened by AES */
+ VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
+ if (VDI_handle<1) {
+ fprintf(stderr,"Wrong VDI handle %d returned by AES\n",VDI_handle);
+ return 1;
+ }
+
+ /* Open virtual VDI workstation */
+ work_in[0]=Getrez()+2;
+ for(i = 1; i < 10; i++)
+ work_in[i] = 1;
+ work_in[10] = 2;
+
+ v_opnvwk(work_in, &VDI_handle, work_out);
+ if (VDI_handle == 0) {
+ fprintf(stderr,"Can not open VDI virtual workstation\n");
+ return 1;
+ }
+
+ /* Read fullscreen size */
+ VDI_w = work_out[0] + 1;
+ VDI_h = work_out[1] + 1;
+
+ /* Read desktop size and position */
+ if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
+ fprintf(stderr,"Can not read desktop properties\n");
+ return 1;
+ }
+
+ /* Read bit depth */
+ vq_extnd(VDI_handle, 1, work_out);
+ VDI_bpp = work_out[4];
+ VDI_oldnumcolors=0;
+
+ switch(VDI_bpp) {
+ case 8:
+ VDI_pixelsize=1;
+ break;
+ case 15:
+ case 16:
+ VDI_pixelsize=2;
+ break;
+ case 24:
+ VDI_pixelsize=3;
+ break;
+ case 32:
+ VDI_pixelsize=4;
+ break;
+ default:
+ fprintf(stderr,"%d bits colour depth not supported\n",VDI_bpp);
+ return 1;
+ }
+
+ /* Setup hardware -> VDI palette mapping */
+ for(i = 16; i < 255; i++) {
+ vdi_index[i] = i;
+ }
+ vdi_index[255] = 1;
+
+ /* Save current palette */
+ if (VDI_bpp>8) {
+ VDI_oldnumcolors=1<<8;
+ } else {
+ VDI_oldnumcolors=1<<VDI_bpp;
+ }
+
+ for(i = 0; i < VDI_oldnumcolors; i++) {
+ short rgb[3];
+
+ vq_color(VDI_handle, i, 0, rgb);
+
+ VDI_oldpalette[i][0] = rgb[0];
+ VDI_oldpalette[i][1] = rgb[1];
+ VDI_oldpalette[i][2] = rgb[2];
+ }
+ VDI_setpalette = GEM_SetNewPalette;
+ SDL_memcpy(VDI_curpalette,VDI_oldpalette,sizeof(VDI_curpalette));
+
+ /* Setup screen info */
+ GEM_title_name = empty_name;
+ GEM_icon_name = empty_name;
+
+ GEM_handle = -1;
+ GEM_locked = SDL_FALSE;
+ GEM_win_fulled = SDL_FALSE;
+ GEM_fullscreen = SDL_FALSE;
+ GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers are setup */
+
+ VDI_screen = NULL;
+ VDI_pitch = VDI_w * VDI_pixelsize;
+ VDI_format = ( (VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
+ VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
+ VDI_ReadExtInfo(this, work_out);
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, VDI_pitch);
+ printf("sdl:video:gem: format=%d\n", VDI_format);
+ printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask
+ );
+#endif
+
+ /* Setup destination mfdb */
+ VDI_dst_mfdb.fd_addr = NULL;
+
+ /* Determine the current screen size */
+ this->info.current_w = VDI_w;
+ this->info.current_h = VDI_h;
+
+ /* Determine the screen depth */
+ /* we change this during the SDL_SetVideoMode implementation... */
+ vformat->BitsPerPixel = VDI_bpp;
+
+ /* Set mouse cursor to arrow */
+ graf_mouse(ARROW, NULL);
+ GEM_cursor = NULL;
+
+ /* Init chunky to planar routine */
+ SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
+
+ /* Setup VDI fill functions */
+ vsf_color(VDI_handle,0);
+ vsf_interior(VDI_handle,1);
+ vsf_perimeter(VDI_handle,0);
+
+ /* Menu bar save buffer */
+ menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
+ GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
+
+ /* Fill video modes list */
+ SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect));
+ SDL_modelist[0]->x = 0;
+ SDL_modelist[0]->y = 0;
+ SDL_modelist[0]->w = VDI_w;
+ SDL_modelist[0]->h = VDI_h;
+
+ SDL_modelist[1] = NULL;
+
+#if SDL_VIDEO_OPENGL
+ SDL_AtariGL_InitPointers(this);
+#endif
+
+ this->info.wm_available = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if (format->BitsPerPixel != VDI_bpp) {
+ return ((SDL_Rect **)NULL);
+ }
+
+ if (flags & SDL_FULLSCREEN) {
+ return (SDL_modelist);
+ }
+
+ return((SDL_Rect **)-1);
+}
+
+static void GEM_FreeBuffers(_THIS)
+{
+ /* Release buffer */
+ if ( GEM_buffer2 ) {
+ Mfree( GEM_buffer2 );
+ GEM_buffer2=NULL;
+ }
+
+ if ( GEM_buffer1 ) {
+ Mfree( GEM_buffer1 );
+ GEM_buffer1=NULL;
+ }
+}
+
+static void GEM_ClearRect(_THIS, short *rect)
+{
+ short oldrgb[3], rgb[3]={0,0,0};
+
+ vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
+ vs_color(VDI_handle, vdi_index[0], rgb);
+
+ vsf_color(VDI_handle,0);
+ vsf_interior(VDI_handle,1);
+ vsf_perimeter(VDI_handle,0);
+ v_bar(VDI_handle, rect);
+
+ vs_color(VDI_handle, vdi_index[0], oldrgb);
+}
+
+static void GEM_ClearScreen(_THIS)
+{
+ short pxy[4];
+
+ v_hide_c(VDI_handle);
+
+ pxy[0] = pxy[1] = 0;
+ pxy[2] = VDI_w - 1;
+ pxy[3] = VDI_h - 1;
+ GEM_ClearRect(this, pxy);
+
+ v_show_c(VDI_handle, 1);
+}
+
+static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3])
+{
+ int i;
+ short rgb[3];
+
+ if (VDI_oldnumcolors==0)
+ return;
+
+ for(i = 0; i < VDI_oldnumcolors; i++) {
+ rgb[0] = newpal[i][0];
+ rgb[1] = newpal[i][1];
+ rgb[2] = newpal[i][2];
+
+ vs_color(VDI_handle, i, rgb);
+ }
+}
+
+static void GEM_LockScreen(_THIS)
+{
+ if (!GEM_locked) {
+ /* Lock AES */
+ wind_update(BEG_UPDATE);
+ wind_update(BEG_MCTRL);
+ /* Reserve memory space, used to be sure of compatibility */
+ form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
+
+ /* Save menu bar */
+ if (GEM_menubar) {
+ MFDB mfdb_src;
+ short blitcoords[8];
+
+ mfdb_src.fd_addr=GEM_menubar;
+ mfdb_src.fd_w=GEM_desk_w;
+ mfdb_src.fd_h=GEM_desk_y;
+ mfdb_src.fd_wdwidth=GEM_desk_w>>4;
+ mfdb_src.fd_nplanes=VDI_bpp;
+ mfdb_src.fd_stand=
+ mfdb_src.fd_r1=
+ mfdb_src.fd_r2=
+ mfdb_src.fd_r3= 0;
+
+ blitcoords[0] = blitcoords[4] = 0;
+ blitcoords[1] = blitcoords[5] = 0;
+ blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
+ blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
+
+ vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
+ }
+
+ GEM_locked=SDL_TRUE;
+ }
+}
+
+static void GEM_UnlockScreen(_THIS)
+{
+ if (GEM_locked) {
+ /* Restore menu bar */
+ if (GEM_menubar) {
+ MFDB mfdb_src;
+ short blitcoords[8];
+
+ mfdb_src.fd_addr=GEM_menubar;
+ mfdb_src.fd_w=GEM_desk_w;
+ mfdb_src.fd_h=GEM_desk_y;
+ mfdb_src.fd_wdwidth=GEM_desk_w>>4;
+ mfdb_src.fd_nplanes=VDI_bpp;
+ mfdb_src.fd_stand=
+ mfdb_src.fd_r1=
+ mfdb_src.fd_r2=
+ mfdb_src.fd_r3= 0;
+
+ blitcoords[0] = blitcoords[4] = 0;
+ blitcoords[1] = blitcoords[5] = 0;
+ blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
+ blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
+
+ vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
+ }
+
+ /* Restore screen memory, and send REDRAW to all apps */
+ form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
+ /* Unlock AES */
+ wind_update(END_MCTRL);
+ wind_update(END_UPDATE);
+
+ GEM_locked=SDL_FALSE;
+ }
+}
+
+SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Uint32 modeflags, screensize;
+ SDL_bool use_shadow1, use_shadow2;
+
+ /* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
+ if ((width & 15) != 0) {
+ width = (width | 15) +1;
+ }
+
+ /*--- Verify if asked mode can be used ---*/
+ if (VDI_bpp != bpp) {
+ SDL_SetError("%d bpp mode not supported", bpp);
+ return(NULL);
+ }
+
+ if (flags & SDL_FULLSCREEN) {
+ if ((VDI_w < width) || (VDI_h < height)) {
+ SDL_SetError("%dx%d mode is too large", width, height);
+ return(NULL);
+ }
+ }
+
+ /*--- Allocate the new pixel format for the screen ---*/
+ if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ screensize = width * height * VDI_pixelsize;
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);
+#endif
+
+ /*--- Allocate shadow buffers if needed, and conversion operations ---*/
+ GEM_FreeBuffers(this);
+
+ GEM_bufops=0;
+ use_shadow1=use_shadow2=SDL_FALSE;
+ if (VDI_screen && (flags & SDL_FULLSCREEN)) {
+ if (VDI_format==VDI_FORMAT_INTER) {
+ use_shadow1=SDL_TRUE;
+ GEM_bufops = B2S_C2P_1TOS;
+ }
+ } else {
+ use_shadow1=SDL_TRUE;
+ if (VDI_format==VDI_FORMAT_PACK) {
+ GEM_bufops = B2S_VROCPYFM_1TOS;
+ } else {
+ use_shadow2=SDL_TRUE;
+ GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS;
+ }
+ }
+
+ if (use_shadow1) {
+ GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
+ if (GEM_buffer1==NULL) {
+ SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10);
+ return NULL;
+ }
+ SDL_memset(GEM_buffer1, 0, screensize);
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");
+#endif
+ }
+
+ if (use_shadow2) {
+ GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
+ if (GEM_buffer2==NULL) {
+ SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10);
+ return NULL;
+ }
+ SDL_memset(GEM_buffer2, 0, screensize);
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");
+#endif
+ }
+
+ /*--- Initialize screen ---*/
+ modeflags = SDL_PREALLOC;
+ if (VDI_bpp == 8) {
+ modeflags |= SDL_HWPALETTE;
+ }
+
+ if (flags & SDL_FULLSCREEN) {
+ GEM_LockScreen(this);
+
+ GEM_ClearScreen(this);
+
+ modeflags |= SDL_FULLSCREEN;
+ if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) {
+ modeflags |= SDL_HWSURFACE;
+ } else {
+ modeflags |= SDL_SWSURFACE;
+ }
+
+ GEM_fullscreen = SDL_TRUE;
+ } else {
+ int old_win_type;
+ short x2,y2,w2,h2;
+
+ GEM_UnlockScreen(this);
+
+ /* Set window gadgets */
+ old_win_type = GEM_win_type;
+ if (!(flags & SDL_NOFRAME)) {
+ GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
+ if (flags & SDL_RESIZABLE) {
+ GEM_win_type |= FULLER|SIZER;
+ modeflags |= SDL_RESIZABLE;
+ }
+ } else {
+ GEM_win_type=0;
+ modeflags |= SDL_NOFRAME;
+ }
+ modeflags |= SDL_SWSURFACE;
+
+ /* Recreate window ? only for different widget or non-created window */
+ if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
+ /* Calculate window size */
+ if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width,height, &x2,&y2,&w2,&h2)) {
+ GEM_FreeBuffers(this);
+ SDL_SetError("Can not calculate window attributes");
+ return NULL;
+ }
+
+ /* Center window */
+ x2 = (GEM_desk_w-w2)>>1;
+ y2 = (GEM_desk_h-h2)>>1;
+ if (x2<0) {
+ x2 = 0;
+ }
+ if (y2<0) {
+ y2 = 0;
+ }
+ x2 += GEM_desk_x;
+ y2 += GEM_desk_y;
+
+ /* Destroy existing window */
+ if (GEM_handle >= 0) {
+ wind_close(GEM_handle);
+ wind_delete(GEM_handle);
+ }
+
+ /* Create window */
+ GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
+ if (GEM_handle<0) {
+ GEM_FreeBuffers(this);
+ SDL_SetError("Can not create window");
+ return NULL;
+ }
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: handle=%d\n", GEM_handle);
+#endif
+
+ /* Setup window name */
+ wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
+ GEM_refresh_name = SDL_FALSE;
+
+ /* Open the window */
+ wind_open(GEM_handle,x2,y2,w2,h2);
+ } else {
+ /* Resize window to fit asked video mode */
+ wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
+ if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) {
+ wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
+ }
+ }
+
+ GEM_fullscreen = SDL_FALSE;
+ }
+
+ /* Set up the new mode framebuffer */
+ current->w = width;
+ current->h = height;
+ if (use_shadow1) {
+ current->pixels = GEM_buffer1;
+ current->pitch = width * VDI_pixelsize;
+ } else {
+ current->pixels = VDI_screen;
+ current->pitch = VDI_pitch;
+ }
+
+#if SDL_VIDEO_OPENGL
+ if (flags & SDL_OPENGL) {
+ if (!SDL_AtariGL_Init(this, current)) {
+ GEM_FreeBuffers(this);
+ SDL_SetError("Can not create OpenGL context");
+ return NULL;
+ }
+
+ modeflags |= SDL_OPENGL;
+ }
+#endif
+
+ current->flags = modeflags;
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
+#endif
+
+ this->UpdateRects = GEM_UpdateRects;
+ GEM_lock_redraw = SDL_FALSE; /* Enable redraw */
+
+ /* We're done */
+ return(current);
+}
+
+static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return -1;
+}
+
+static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
+{
+ SDL_Surface *surface;
+ int i, surf_width;
+
+ surface = this->screen;
+ /* Need to be a multiple of 16 pixels */
+ surf_width=surface->w;
+ if ((surf_width & 15) != 0) {
+ surf_width = (surf_width | 15) + 1;
+ }
+
+ if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
+ void *destscr;
+ int destpitch;
+
+ if (GEM_bufops & B2S_C2P_1TOS) {
+ destscr = VDI_screen;
+ destpitch = VDI_pitch;
+ } else {
+ destscr = GEM_buffer2;
+ destpitch = surface->pitch;
+ }
+
+ for (i=0;i<numrects;i++) {
+ void *source,*destination;
+ int x1,x2;
+
+ x1 = rects[i].x & ~15;
+ x2 = rects[i].x+rects[i].w;
+ if (x2 & 15) {
+ x2 = (x2 | 15) +1;
+ }
+
+ source = surface->pixels;
+ source += surface->pitch * rects[i].y;
+ source += x1;
+
+ destination = destscr;
+ destination += destpitch * rects[i].y;
+ destination += x1;
+
+ SDL_Atari_C2pConvert(
+ source, destination,
+ x2-x1, rects[i].h,
+ SDL_FALSE,
+ surface->pitch, destpitch
+ );
+ }
+ }
+
+ if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
+ MFDB mfdb_src;
+ short blitcoords[8];
+
+ mfdb_src.fd_addr=surface->pixels;
+ mfdb_src.fd_w=surf_width;
+ mfdb_src.fd_h=surface->h;
+ mfdb_src.fd_wdwidth= (surface->pitch/VDI_pixelsize) >> 4;
+ mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
+ mfdb_src.fd_stand=
+ mfdb_src.fd_r1=
+ mfdb_src.fd_r2=
+ mfdb_src.fd_r3= 0;
+ if (GEM_bufops & B2S_VROCPYFM_2TOS) {
+ mfdb_src.fd_addr=GEM_buffer2;
+ }
+
+ for ( i=0; i<numrects; ++i ) {
+ blitcoords[0] = blitcoords[4] = rects[i].x;
+ blitcoords[1] = blitcoords[5] = rects[i].y;
+ blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1;
+ blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1;
+
+ vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
+ }
+ }
+}
+
+static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
+{
+ short pxy[4], wind_pxy[4];
+ int i;
+
+ if (wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
+ return;
+ }
+
+ for ( i=0; i<numrects; ++i ) {
+ pxy[0] = wind_pxy[0] + rects[i].x;
+ pxy[1] = wind_pxy[1] + rects[i].y;
+ pxy[2] = rects[i].w;
+ pxy[3] = rects[i].h;
+
+ GEM_wind_redraw(this, GEM_handle, pxy);
+ }
+}
+
+static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ SDL_Surface *surface;
+
+ if (GEM_lock_redraw) {
+ return;
+ }
+
+ surface = this->screen;
+
+ if (surface->flags & SDL_FULLSCREEN) {
+ GEM_UpdateRectsFullscreen(this, numrects, rects);
+ } else {
+ GEM_UpdateRectsWindowed(this, numrects, rects);
+ }
+}
+
+static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
+{
+ int surf_width;
+
+ /* Need to be a multiple of 16 pixels */
+ surf_width=surface->w;
+ if ((surf_width & 15) != 0) {
+ surf_width = (surf_width | 15) + 1;
+ }
+
+ if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
+ void *destscr;
+ int destpitch;
+
+ if (GEM_bufops & B2S_C2P_1TOS) {
+ destscr = VDI_screen;
+ destpitch = VDI_pitch;
+ } else {
+ destscr = GEM_buffer2;
+ destpitch = surface->pitch;
+ }
+
+ SDL_Atari_C2pConvert(
+ surface->pixels, destscr,
+ surf_width, surface->h,
+ SDL_FALSE,
+ surface->pitch, destpitch
+ );
+ }
+
+ if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
+ MFDB mfdb_src;
+ short blitcoords[8];
+
+ mfdb_src.fd_w=surf_width;
+ mfdb_src.fd_h=surface->h;
+ mfdb_src.fd_wdwidth=mfdb_src.fd_w >> 4;
+ mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
+ mfdb_src.fd_stand=
+ mfdb_src.fd_r1=
+ mfdb_src.fd_r2=
+ mfdb_src.fd_r3= 0;
+ if (GEM_bufops & B2S_VROCPYFM_1TOS) {
+ mfdb_src.fd_addr=surface->pixels;
+ } else {
+ mfdb_src.fd_addr=GEM_buffer2;
+ }
+
+ blitcoords[0] = blitcoords[4] = 0;
+ blitcoords[1] = blitcoords[5] = 0;
+ blitcoords[2] = blitcoords[6] = surface->w - 1;
+ blitcoords[3] = blitcoords[7] = surface->h - 1;
+
+ vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
+ }
+
+ return(0);
+}
+
+static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
+{
+ short pxy[8];
+
+ /* Update the whole window */
+ wind_get(GEM_handle, WF_WORKXYWH, &pxy[0], &pxy[1], &pxy[2], &pxy[3]);
+
+ GEM_wind_redraw(this, GEM_handle, pxy);
+
+ return(0);
+}
+
+static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (GEM_lock_redraw) {
+ return(0);
+ }
+
+ if (surface->flags & SDL_FULLSCREEN) {
+ return GEM_FlipHWSurfaceFullscreen(this, surface);
+ } else {
+ return GEM_FlipHWSurfaceWindowed(this, surface);
+ }
+}
+
+static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ SDL_Surface *surface;
+
+#ifdef DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: setcolors()\n");
+#endif
+
+ /* Do not change palette in True Colour */
+ surface = this->screen;
+ if (surface->format->BitsPerPixel > 8) {
+ return 1;
+ }
+
+ for(i = 0; i < ncolors; i++)
+ {
+ int r, g, b;
+ short rgb[3];
+
+ r = colors[i].r;
+ g = colors[i].g;
+ b = colors[i].b;
+
+ rgb[0] = VDI_curpalette[i][0] = (1000 * r) / 255;
+ rgb[1] = VDI_curpalette[i][1] =(1000 * g) / 255;
+ rgb[2] = VDI_curpalette[i][2] =(1000 * b) / 255;
+
+ vs_color(VDI_handle, vdi_index[firstcolor+i], rgb);
+ }
+
+ return(1);
+}
+
+#if 0
+static int GEM_ToggleFullScreen(_THIS, int on)
+{
+ if (on) {
+ GEM_LockScreen(this);
+ } else {
+ GEM_UnlockScreen(this);
+ }
+
+ return(1);
+}
+#endif
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void GEM_VideoQuit(_THIS)
+{
+ SDL_AtariXbios_RestoreVectors();
+ if (GEM_usedevmouse) {
+ SDL_AtariDevMouse_Close();
+ }
+
+ GEM_FreeBuffers(this);
+
+#if SDL_VIDEO_OPENGL
+ if (gl_active) {
+ SDL_AtariGL_Quit(this, SDL_TRUE);
+ }
+#endif
+
+ /* Destroy window */
+ if (GEM_handle>=0) {
+ wind_close(GEM_handle);
+ wind_delete(GEM_handle);
+ GEM_handle=-1;
+ }
+
+ GEM_UnlockScreen(this);
+ if (GEM_menubar) {
+ Mfree(GEM_menubar);
+ GEM_menubar=NULL;
+ }
+
+ appl_exit();
+
+ GEM_SetNewPalette(this, VDI_oldpalette);
+
+ /* Close VDI workstation */
+ if (VDI_handle) {
+ v_clsvwk(VDI_handle);
+ }
+
+ /* Free mode list */
+ if (SDL_modelist[0]) {
+ SDL_free(SDL_modelist[0]);
+ SDL_modelist[0]=NULL;
+ }
+
+ this->screen->pixels = NULL;
+}
+
+void GEM_wind_redraw(_THIS, int winhandle, short *inside)
+{
+ short todo[4];
+
+ /* Tell AES we are going to update */
+ wind_update(BEG_UPDATE);
+
+ v_hide_c(VDI_handle);
+
+ /* Browse the rectangle list to redraw */
+ if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
+
+ while (todo[2] && todo[3]) {
+
+ if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
+ todo[2] += todo[0]-1;
+ todo[3] += todo[1]-1;
+ refresh_window(this, winhandle, todo);
+ }
+
+ if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ }
+
+ }
+
+ /* Update finished */
+ wind_update(END_UPDATE);
+
+ v_show_c(VDI_handle,1);
+}
+
+static void refresh_window(_THIS, int winhandle, short *rect)
+{
+ MFDB mfdb_src;
+ short pxy[8],wind_pxy[8];
+ SDL_Surface *surface;
+ int iconified;
+
+ /* Is window iconified ? */
+ iconified = 0;
+/* if (GEM_wfeatures & (1<<WF_ICONIFY))*/ {
+ if (wind_get(winhandle, WF_ICONIFY, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])!=0) {
+ iconified = wind_pxy[0];
+ }
+ }
+
+ if (wind_get(winhandle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
+ return;
+ }
+
+ if (iconified && GEM_icon) {
+ short icon_rect[4], dst_rect[4];
+ short iconx,icony;
+
+ surface = GEM_icon;
+
+ GEM_ClearRect(this, rect);
+
+ /* Calculate centered icon(x,y,w,h) relative to window */
+ iconx = (wind_pxy[2]-surface->w)>>1;
+ icony = (wind_pxy[3]-surface->h)>>1;
+
+ icon_rect[0] = iconx;
+ icon_rect[1] = icony;
+ icon_rect[2] = surface->w;
+ icon_rect[3] = surface->h;
+
+ /* Calculate redraw rectangle(x,y,w,h) relative to window */
+ dst_rect[0] = rect[0]-wind_pxy[0];
+ dst_rect[1] = rect[1]-wind_pxy[1];
+ dst_rect[2] = rect[2]-rect[0]+1;
+ dst_rect[3] = rect[3]-rect[1]+1;
+
+ /* Does the icon rectangle must be redrawn ? */
+ if (!rc_intersect((GRECT *)icon_rect, (GRECT *)dst_rect)) {
+ return;
+ }
+
+#if DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: clip(0,0,%d,%d) to (%d,%d,%d,%d)\n",
+ surface->w-1,surface->h-1, dst_rect[0],dst_rect[1],dst_rect[2],dst_rect[3]);
+ printf("sdl:video:gem: icon(%d,%d,%d,%d)\n",
+ icon_rect[0], icon_rect[1], icon_rect[2], icon_rect[3]);
+ printf("sdl:video:gem: refresh_window(): draw icon\n");
+#endif
+
+ /* Calculate icon(x1,y1,x2,y2) relative to screen */
+ icon_rect[0] += wind_pxy[0];
+ icon_rect[1] += wind_pxy[1];
+ icon_rect[2] += icon_rect[0]-1;
+ icon_rect[3] += icon_rect[1]-1;
+
+ /* Calculate intersection rectangle to redraw */
+ pxy[4]=pxy[0]=MAX(icon_rect[0],rect[0]);
+ pxy[5]=pxy[1]=MAX(icon_rect[1],rect[1]);
+ pxy[6]=pxy[2]=MIN(icon_rect[2],rect[2]);
+ pxy[7]=pxy[3]=MIN(icon_rect[3],rect[3]);
+
+ /* Calculate icon source image pos relative to window */
+ pxy[0] -= wind_pxy[0]+iconx;
+ pxy[1] -= wind_pxy[1]+icony;
+ pxy[2] -= wind_pxy[0]+iconx;
+ pxy[3] -= wind_pxy[1]+icony;
+
+ } else {
+ surface = this->screen;
+
+#if DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: refresh_window(): draw frame buffer\n");
+#endif
+
+ /* Redraw all window content */
+ pxy[0] = rect[0]-wind_pxy[0];
+ pxy[1] = rect[1]-wind_pxy[1];
+ pxy[2] = rect[2]-wind_pxy[0];
+ pxy[3] = rect[3]-wind_pxy[1];
+
+ pxy[4] = rect[0];
+ pxy[5] = rect[1];
+ pxy[6] = rect[2];
+ pxy[7] = rect[3];
+ }
+
+ if (GEM_bufops & B2S_C2P_1TO2) {
+ void *src, *dest;
+ int x1,x2;
+
+ x1 = (rect[0]-wind_pxy[0]) & ~15;
+ x2 = rect[2]-wind_pxy[0];
+ if (x2 & 15) {
+ x2 = (x2 | 15) +1;
+ }
+
+ src = surface->pixels;
+ src += surface->pitch * (rect[1]-wind_pxy[1]);
+ src += x1;
+
+ dest = GEM_buffer2;
+ dest += surface->pitch * (rect[1]-wind_pxy[1]);
+ dest += x1;
+
+ SDL_Atari_C2pConvert(
+ src, dest,
+ x2-x1, rect[3]-rect[1]+1,
+ SDL_FALSE,
+ surface->pitch, surface->pitch
+ );
+ }
+
+ mfdb_src.fd_addr=surface->pixels;
+ {
+ int width;
+
+ /* Need to be a multiple of 16 pixels */
+ width=surface->w;
+ if ((width & 15) != 0) {
+ width = (width | 15) + 1;
+ }
+ mfdb_src.fd_w=width;
+ }
+ mfdb_src.fd_h=surface->h;
+ mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
+ mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
+ mfdb_src.fd_stand=
+ mfdb_src.fd_r1=
+ mfdb_src.fd_r2=
+ mfdb_src.fd_r3= 0;
+
+ if (GEM_bufops & B2S_VROCPYFM_2TOS) {
+ mfdb_src.fd_addr=GEM_buffer2;
+ }
+
+#if DEBUG_VIDEO_GEM
+ printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n",
+ surface->w, surface->h,
+ pxy[0],pxy[1],pxy[2],pxy[3],
+ pxy[4],pxy[5],pxy[6],pxy[7]
+ );
+#endif
+
+ vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
+}
+
+#if SDL_VIDEO_OPENGL
+
+static void GEM_GL_SwapBuffers(_THIS)
+{
+ SDL_AtariGL_SwapBuffers(this);
+ GEM_FlipHWSurface(this, this->screen);
+}
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.h b/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.h
new file mode 100644
index 0000000..f3a1954
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemvideo.h
@@ -0,0 +1,191 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_gemvideo_h
+#define _SDL_gemvideo_h
+
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ MFORM *mform_p;
+};
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+/* Functions prototypes */
+void GEM_wind_redraw(_THIS, int winhandle, short *inside);
+
+/* Private display data */
+
+#define B2S_C2P_1TO2 (1<<0) /* C2P convert buffer 1 to buffer 2 */
+#define B2S_C2P_1TOS (1<<1) /* C2P convert buffer 1 to screen */
+#define B2S_VROCPYFM_1TOS (1<<2) /* vro_cpyfm() buffer 1 to screen */
+#define B2S_VROCPYFM_2TOS (1<<3) /* vro_cpyfm() buffer 2 to screen */
+
+#define SDL_NUMMODES 1 /* Fullscreen */
+
+struct SDL_PrivateVideoData {
+ Uint16 buf2scr_ops; /* Operations to get buffer to screen */
+ void *buffer1; /* Our shadow buffers */
+ void *buffer2;
+
+ /* VDI infos */
+ short vdi_handle; /* VDI handle */
+ short full_w, full_h; /* Fullscreen size */
+ short bpp; /* Colour depth */
+ short pixelsize; /* Bytes per pixel */
+ short old_numcolors; /* Number of colors in saved palette */
+ Uint16 pitch; /* Line length */
+ Uint16 format; /* Screen format */
+ void *screen; /* Screen address */
+ Uint32 red, green, blue, alpha; /* Screen components */
+ Uint32 screensize;
+ short blit_coords[8]; /* Coordinates for bitblt */
+ MFDB src_mfdb, dst_mfdb; /* VDI MFDB for bitblt */
+ Uint16 old_palette[256][3]; /* Saved current palette */
+ Uint16 cur_palette[256][3]; /* SDL application palette */
+ /* Function to set/restore palette */
+ void (*setpalette)(_THIS, Uint16 newpal[256][3]);
+
+ /* GEM infos */
+ short desk_x, desk_y; /* Desktop properties */
+ short desk_w, desk_h;
+ short win_handle; /* Our window handle */
+ int window_type; /* Window type */
+ const char *title_name; /* Window title */
+ const char *icon_name; /* Icon title */
+ short version; /* AES version */
+ short wfeatures; /* AES window features */
+ SDL_bool refresh_name; /* Change window title ? */
+ SDL_bool window_fulled; /* Window maximized ? */
+ SDL_bool mouse_relative; /* Report relative mouse movement */
+ SDL_bool locked; /* AES locked for fullscreen ? */
+ SDL_bool lock_redraw; /* Prevent redraw till buffers are setup */
+ short message[8]; /* To self-send an AES message */
+ void *menubar; /* Menu bar save buffer when going fullscreen */
+ SDL_bool use_dev_mouse; /* Use /dev/mouse ? */
+ WMcursor *cursor; /* To restore cursor when leaving/entering window */
+
+ SDL_bool fullscreen; /* Fullscreen or windowed mode ? */
+ SDL_Rect *SDL_modelist[SDL_NUMMODES+1]; /* Mode list */
+ SDL_Surface *icon; /* The icon */
+};
+
+/* Hidden structure -> variables names */
+#define VDI_handle (this->hidden->vdi_handle)
+#define VDI_w (this->hidden->full_w)
+#define VDI_h (this->hidden->full_h)
+#define VDI_bpp (this->hidden->bpp)
+#define VDI_pixelsize (this->hidden->pixelsize)
+#define VDI_oldnumcolors (this->hidden->old_numcolors)
+#define VDI_oldpalette (this->hidden->old_palette)
+#define VDI_curpalette (this->hidden->cur_palette)
+#define VDI_setpalette (this->hidden->setpalette)
+#define VDI_pitch (this->hidden->pitch)
+#define VDI_format (this->hidden->format)
+#define VDI_screen (this->hidden->screen)
+#define VDI_redmask (this->hidden->red)
+#define VDI_greenmask (this->hidden->green)
+#define VDI_bluemask (this->hidden->blue)
+#define VDI_alphamask (this->hidden->alpha)
+#define VDI_screensize (this->hidden->screensize)
+#define VDI_src_mfdb (this->hidden->src_mfdb)
+#define VDI_dst_mfdb (this->hidden->dst_mfdb)
+#define VDI_blit_coords (this->hidden->blit_coords)
+
+#define GEM_desk_x (this->hidden->desk_x)
+#define GEM_desk_y (this->hidden->desk_y)
+#define GEM_desk_w (this->hidden->desk_w)
+#define GEM_desk_h (this->hidden->desk_h)
+#define GEM_handle (this->hidden->win_handle)
+#define GEM_win_type (this->hidden->window_type)
+#define GEM_title_name (this->hidden->title_name)
+#define GEM_icon_name (this->hidden->icon_name)
+#define GEM_refresh_name (this->hidden->refresh_name)
+#define GEM_version (this->hidden->version)
+#define GEM_wfeatures (this->hidden->wfeatures)
+#define GEM_win_fulled (this->hidden->window_fulled)
+#define GEM_mouse_relative (this->hidden->mouse_relative)
+#define GEM_locked (this->hidden->locked)
+#define GEM_lock_redraw (this->hidden->lock_redraw)
+#define GEM_message (this->hidden->message)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define GEM_icon (this->hidden->icon)
+#define GEM_fullscreen (this->hidden->fullscreen)
+#define GEM_menubar (this->hidden->menubar)
+#define GEM_usedevmouse (this->hidden->use_dev_mouse)
+#define GEM_cursor (this->hidden->cursor)
+
+#define GEM_buffer1 (this->hidden->buffer1)
+#define GEM_buffer2 (this->hidden->buffer2)
+#define GEM_bufops (this->hidden->buf2scr_ops)
+
+#define VDI_FBMASK(amask, rmask, gmask, bmask) \
+ VDI_alphamask = (amask); \
+ VDI_redmask = (rmask); \
+ VDI_greenmask = (gmask); \
+ VDI_bluemask = (bmask);
+
+/*
+ Possible buffer to screen operations:
+
+ TC: 8 (chunky),15,16,24,32 bpp
+ 8I: 8 bpp planes
+ FB: screen framebuffer address available
+ FS: fullscreen
+
+ TC, FB, FS:
+ - draw to screen
+ 8I, FB, FS:
+ - draw to buffer 1
+ - C2P from buffer 1 to screen
+
+ TC, !FB, FS:
+ - draw to buffer 1
+ - vro_cpyfm() from buffer 1 to screen
+ 8I, !FB, FS:
+ - draw to buffer 1
+ - C2P from buffer 1 to buffer 2
+ - vro_cpyfm() from buffer 2 to screen
+
+ TC, FB, !FS:
+ - draw to buffer 1
+ - vro_cpyfm() from buffer 1 to screen
+ 8I, FB, !FS:
+ - draw to buffer 1
+ - C2P from buffer 1 to buffer 2
+ - vro_cpyfm() from buffer 2 to screen
+
+ TC, !FB, !FS:
+ - draw to buffer 1
+ - vro_cpyfm() from buffer 1 to screen
+ 8I, !FB, !FS:
+ - draw to buffer 1
+ - C2P from buffer 1 to buffer 2
+ - vro_cpyfm() from buffer 2 to screen
+*/
+
+#endif /* _SDL_gemvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm.c b/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm.c
new file mode 100644
index 0000000..10776fd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm.c
@@ -0,0 +1,116 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ GEM SDL video driver
+ Window manager functions
+
+ Patrice Mandin
+*/
+
+/* Mint includes */
+#include <gem.h>
+
+#include "SDL_gemwm_c.h"
+
+/* Defines */
+
+#define ICONWIDTH 64
+#define ICONHEIGHT 64
+
+/* Functions */
+
+void GEM_SetCaption(_THIS, const char *title, const char *icon)
+{
+ if (title) {
+ GEM_title_name = title;
+ GEM_refresh_name = SDL_TRUE;
+ }
+
+ if (icon) {
+ GEM_icon_name = icon;
+ GEM_refresh_name = SDL_TRUE;
+ }
+}
+
+void GEM_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
+{
+ SDL_Surface *sicon;
+ SDL_Rect bounds;
+
+#if 0
+ if ((GEM_wfeatures & (1<<WF_ICONIFY))==0) {
+ return;
+ }
+#endif
+
+ if (icon == NULL) {
+ return;
+ }
+
+ /* Convert icon to the screen format */
+ sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
+ VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, 0);
+ if ( sicon == NULL ) {
+ return;
+ }
+
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = icon->w;
+ bounds.h = icon->h;
+ if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 ) {
+ SDL_FreeSurface(sicon);
+ return;
+ }
+
+ GEM_icon = sicon;
+}
+
+int GEM_IconifyWindow(_THIS)
+{
+ if ((GEM_wfeatures & (1<<WF_ICONIFY))==0)
+ return 0;
+
+ GEM_message[0] = WM_ICONIFY;
+ GEM_message[1] = gl_apid;
+ GEM_message[2] = 0;
+ GEM_message[3] = GEM_handle;
+ GEM_message[4] = 0;
+ GEM_message[5] = GEM_desk_h-ICONHEIGHT;
+ GEM_message[6] = ICONWIDTH;
+ GEM_message[7] = ICONHEIGHT;
+
+ appl_write(gl_apid, sizeof(GEM_message), GEM_message);
+
+ return 1;
+}
+
+SDL_GrabMode GEM_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ if (this->screen == NULL) {
+ return SDL_GRAB_OFF;
+ }
+
+ return mode;
+}
diff --git a/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm_c.h b/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm_c.h
new file mode 100644
index 0000000..59828b7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/gem/SDL_gemwm_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * GEM SDL video driver implementation
+ * Window manager functions
+ *
+ * Patrice Mandin
+ */
+
+#include "SDL_gemvideo.h"
+
+/* Functions prototypes */
+extern void GEM_SetCaption(_THIS, const char *title, const char *icon);
+extern void GEM_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask);
+extern int GEM_IconifyWindow(_THIS);
+extern SDL_GrabMode GEM_GrabInput(_THIS, SDL_GrabMode mode);
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents.c b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents.c
new file mode 100644
index 0000000..d963fe1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents.c
@@ -0,0 +1,264 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting GGI events into SDL events */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#include <ggi/keyboard.h>
+
+#include "SDL_ggikeys.h"
+
+#include "SDL.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ggivideo.h"
+#include "SDL_ggievents_c.h"
+
+/* The translation tables from a GGI keycode to a SDL keysym */
+static SDLKey keymap[128];
+static SDL_keysym *GGI_TranslateKey(ggi_event *ev, SDL_keysym *keysym);
+
+static int posted = 0;
+
+void GGI_PumpEvents(_THIS)
+{
+ struct timeval *tvp, tv = { 0, 0 };
+ ggi_event ev;
+
+ tvp = &tv;
+
+/* ggiFlush(VIS); */
+
+ while (ggiEventPoll(VIS, emAll, tvp))
+/* while (ggiEventPoll(VIS, (emKeyboard | emPointer | emCommand), tvp)) */
+ {
+ int queueevent_mouse = 0, queueevent_kbd = 0;
+ static int buttons = 0;
+ static int mouse_x = 0, mouse_y = 0, mouse_z = 0;
+ int x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0;
+ int pressed_mouse, pressed_kbd;
+ SDL_keysym keysym;
+
+ posted = 0;
+
+ /* FIXME: We do not actually want all events, only
+ * mouse and keyboard events. Having to handle all
+ * events will slow things down. */
+
+ ggiEventRead(VIS, &ev, emAll);
+/* ggiEventRead(VIS, &ev, (emKeyboard | emPointer | emCommand)); */
+
+ switch (ev.any.type)
+ {
+ case evPtrRelative:
+ x = ev.pmove.x;
+ y = ev.pmove.y;
+ z = ev.pmove.wheel;
+ posted += SDL_PrivateMouseMotion(0, 1, x, y);
+ break;
+ case evPtrAbsolute:
+ if (mouse_x != ev.pmove.x || mouse_y != ev.pmove.y || mouse_z != ev.pmove.wheel)
+ {
+ x = ev.pmove.x - mouse_x;
+ y = ev.pmove.y - mouse_y;
+ z = ev.pmove.wheel - mouse_z;
+ mouse_x = ev.pmove.x;
+ mouse_y = ev.pmove.y;
+ mouse_z = ev.pmove.wheel;
+ posted += SDL_PrivateMouseMotion(0, 1, x, y);
+ }
+ break;
+ case evPtrButtonPress:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, ev.pbutton.button, 0, 0);
+ break;
+ case evPtrButtonRelease:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, ev.pbutton.button, 0, 0);
+ break;
+ case evKeyPress:
+ case evKeyRepeat:
+ posted += SDL_PrivateKeyboard(SDL_PRESSED, GGI_TranslateKey(&ev, &keysym));
+ break;
+ case evKeyRelease:
+ posted += SDL_PrivateKeyboard(SDL_RELEASED, GGI_TranslateKey(&ev, &keysym));
+ break;
+ case evCommand:
+ fprintf(stderr, "Command event %x recieved\n", ev.cmd.code);
+ break;
+ default:
+ fprintf(stderr, "Unhandled event type %d\n", ev.any.type);
+ break;
+ }
+ }
+
+}
+
+void GGI_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the GGI key translation table */
+ for ( i=0; i<SDL_arraysize(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[SCANCODE_ESCAPE] = SDLK_ESCAPE;
+ keymap[SCANCODE_1] = SDLK_1;
+ keymap[SCANCODE_2] = SDLK_2;
+ keymap[SCANCODE_3] = SDLK_3;
+ keymap[SCANCODE_4] = SDLK_4;
+ keymap[SCANCODE_5] = SDLK_5;
+ keymap[SCANCODE_6] = SDLK_6;
+ keymap[SCANCODE_7] = SDLK_7;
+ keymap[SCANCODE_8] = SDLK_8;
+ keymap[SCANCODE_9] = SDLK_9;
+ keymap[SCANCODE_0] = SDLK_0;
+ keymap[SCANCODE_MINUS] = SDLK_MINUS;
+ keymap[SCANCODE_EQUAL] = SDLK_EQUALS;
+ keymap[SCANCODE_BACKSPACE] = SDLK_BACKSPACE;
+ keymap[SCANCODE_TAB] = SDLK_TAB;
+ keymap[SCANCODE_Q] = SDLK_q;
+ keymap[SCANCODE_W] = SDLK_w;
+ keymap[SCANCODE_E] = SDLK_e;
+ keymap[SCANCODE_R] = SDLK_r;
+ keymap[SCANCODE_T] = SDLK_t;
+ keymap[SCANCODE_Y] = SDLK_y;
+ keymap[SCANCODE_U] = SDLK_u;
+ keymap[SCANCODE_I] = SDLK_i;
+ keymap[SCANCODE_O] = SDLK_o;
+ keymap[SCANCODE_P] = SDLK_p;
+ keymap[SCANCODE_BRACKET_LEFT] = SDLK_LEFTBRACKET;
+ keymap[SCANCODE_BRACKET_RIGHT] = SDLK_RIGHTBRACKET;
+ keymap[SCANCODE_ENTER] = SDLK_RETURN;
+ keymap[SCANCODE_LEFTCONTROL] = SDLK_LCTRL;
+ keymap[SCANCODE_A] = SDLK_a;
+ keymap[SCANCODE_S] = SDLK_s;
+ keymap[SCANCODE_D] = SDLK_d;
+ keymap[SCANCODE_F] = SDLK_f;
+ keymap[SCANCODE_G] = SDLK_g;
+ keymap[SCANCODE_H] = SDLK_h;
+ keymap[SCANCODE_J] = SDLK_j;
+ keymap[SCANCODE_K] = SDLK_k;
+ keymap[SCANCODE_L] = SDLK_l;
+ keymap[SCANCODE_SEMICOLON] = SDLK_SEMICOLON;
+ keymap[SCANCODE_APOSTROPHE] = SDLK_QUOTE;
+ keymap[SCANCODE_GRAVE] = SDLK_BACKQUOTE;
+ keymap[SCANCODE_LEFTSHIFT] = SDLK_LSHIFT;
+ keymap[SCANCODE_BACKSLASH] = SDLK_BACKSLASH;
+ keymap[SCANCODE_Z] = SDLK_z;
+ keymap[SCANCODE_X] = SDLK_x;
+ keymap[SCANCODE_C] = SDLK_c;
+ keymap[SCANCODE_V] = SDLK_v;
+ keymap[SCANCODE_B] = SDLK_b;
+ keymap[SCANCODE_N] = SDLK_n;
+ keymap[SCANCODE_M] = SDLK_m;
+ keymap[SCANCODE_COMMA] = SDLK_COMMA;
+ keymap[SCANCODE_PERIOD] = SDLK_PERIOD;
+ keymap[SCANCODE_SLASH] = SDLK_SLASH;
+ keymap[SCANCODE_RIGHTSHIFT] = SDLK_RSHIFT;
+ keymap[SCANCODE_KEYPADMULTIPLY] = SDLK_KP_MULTIPLY;
+ keymap[SCANCODE_LEFTALT] = SDLK_LALT;
+ keymap[SCANCODE_SPACE] = SDLK_SPACE;
+ keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK;
+ keymap[SCANCODE_F1] = SDLK_F1;
+ keymap[SCANCODE_F2] = SDLK_F2;
+ keymap[SCANCODE_F3] = SDLK_F3;
+ keymap[SCANCODE_F4] = SDLK_F4;
+ keymap[SCANCODE_F5] = SDLK_F5;
+ keymap[SCANCODE_F6] = SDLK_F6;
+ keymap[SCANCODE_F7] = SDLK_F7;
+ keymap[SCANCODE_F8] = SDLK_F8;
+ keymap[SCANCODE_F9] = SDLK_F9;
+ keymap[SCANCODE_F10] = SDLK_F10;
+ keymap[SCANCODE_NUMLOCK] = SDLK_NUMLOCK;
+ keymap[SCANCODE_SCROLLLOCK] = SDLK_SCROLLOCK;
+ keymap[SCANCODE_KEYPAD7] = SDLK_KP7;
+ keymap[SCANCODE_CURSORUPLEFT] = SDLK_KP7;
+ keymap[SCANCODE_KEYPAD8] = SDLK_KP8;
+ keymap[SCANCODE_CURSORUP] = SDLK_KP8;
+ keymap[SCANCODE_KEYPAD9] = SDLK_KP9;
+ keymap[SCANCODE_CURSORUPRIGHT] = SDLK_KP9;
+ keymap[SCANCODE_KEYPADMINUS] = SDLK_KP_MINUS;
+ keymap[SCANCODE_KEYPAD4] = SDLK_KP4;
+ keymap[SCANCODE_CURSORLEFT] = SDLK_KP4;
+ keymap[SCANCODE_KEYPAD5] = SDLK_KP5;
+ keymap[SCANCODE_KEYPAD6] = SDLK_KP6;
+ keymap[SCANCODE_CURSORRIGHT] = SDLK_KP6;
+ keymap[SCANCODE_KEYPADPLUS] = SDLK_KP_PLUS;
+ keymap[SCANCODE_KEYPAD1] = SDLK_KP1;
+ keymap[SCANCODE_CURSORDOWNLEFT] = SDLK_KP1;
+ keymap[SCANCODE_KEYPAD2] = SDLK_KP2;
+ keymap[SCANCODE_CURSORDOWN] = SDLK_KP2;
+ keymap[SCANCODE_KEYPAD3] = SDLK_KP3;
+ keymap[SCANCODE_CURSORDOWNRIGHT] = SDLK_KP3;
+ keymap[SCANCODE_KEYPAD0] = SDLK_KP0;
+ keymap[SCANCODE_KEYPADPERIOD] = SDLK_KP_PERIOD;
+ keymap[SCANCODE_LESS] = SDLK_LESS;
+ keymap[SCANCODE_F11] = SDLK_F11;
+ keymap[SCANCODE_F12] = SDLK_F12;
+ keymap[SCANCODE_KEYPADENTER] = SDLK_KP_ENTER;
+ keymap[SCANCODE_RIGHTCONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_CONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_KEYPADDIVIDE] = SDLK_KP_DIVIDE;
+ keymap[SCANCODE_PRINTSCREEN] = SDLK_PRINT;
+ keymap[SCANCODE_RIGHTALT] = SDLK_RALT;
+ keymap[SCANCODE_BREAK] = SDLK_BREAK;
+ keymap[SCANCODE_BREAK_ALTERNATIVE] = SDLK_UNKNOWN;
+ keymap[SCANCODE_HOME] = SDLK_HOME;
+ keymap[SCANCODE_CURSORBLOCKUP] = SDLK_UP;
+ keymap[SCANCODE_PAGEUP] = SDLK_PAGEUP;
+ keymap[SCANCODE_CURSORBLOCKLEFT] = SDLK_LEFT;
+ keymap[SCANCODE_CURSORBLOCKRIGHT] = SDLK_RIGHT;
+ keymap[SCANCODE_END] = SDLK_END;
+ keymap[SCANCODE_CURSORBLOCKDOWN] = SDLK_DOWN;
+ keymap[SCANCODE_PAGEDOWN] = SDLK_PAGEDOWN;
+ keymap[SCANCODE_INSERT] = SDLK_INSERT;
+ keymap[SCANCODE_REMOVE] = SDLK_DELETE;
+ keymap[119] = SDLK_PAUSE;
+ keymap[SCANCODE_RIGHTWIN] = SDLK_RSUPER;
+ keymap[SCANCODE_LEFTWIN] = SDLK_LSUPER;
+ keymap[127] = SDLK_MENU;
+}
+
+
+
+static SDL_keysym *GGI_TranslateKey(gii_event *ev, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = ev->key.button;
+ keysym->sym = keymap[ev->key.button];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if (SDL_TranslateUNICODE)
+ {
+ keysym->unicode = GII_UNICODE(ev->key.sym);
+ }
+
+ return keysym;
+}
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents_c.h b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents_c.h
new file mode 100755
index 0000000..2c66106
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggievents_c.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_ggivideo.h"
+
+/* Functions to be exported */
+extern void GGI_InitOSKeymap(_THIS);
+extern void GGI_PumpEvents(_THIS);
+
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggikeys.h b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggikeys.h
new file mode 100644
index 0000000..2868ee6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggikeys.h
@@ -0,0 +1,135 @@
+
+#define SCANCODE_ESCAPE 1
+
+#define SCANCODE_1 2
+#define SCANCODE_2 3
+#define SCANCODE_3 4
+#define SCANCODE_4 5
+#define SCANCODE_5 6
+#define SCANCODE_6 7
+#define SCANCODE_7 8
+#define SCANCODE_8 9
+#define SCANCODE_9 10
+#define SCANCODE_0 11
+
+#define SCANCODE_MINUS 12
+#define SCANCODE_EQUAL 13
+
+#define SCANCODE_BACKSPACE 14
+#define SCANCODE_TAB 15
+
+#define SCANCODE_Q 16
+#define SCANCODE_W 17
+#define SCANCODE_E 18
+#define SCANCODE_R 19
+#define SCANCODE_T 20
+#define SCANCODE_Y 21
+#define SCANCODE_U 22
+#define SCANCODE_I 23
+#define SCANCODE_O 24
+#define SCANCODE_P 25
+#define SCANCODE_BRACKET_LEFT 26
+#define SCANCODE_BRACKET_RIGHT 27
+
+#define SCANCODE_ENTER 28
+
+#define SCANCODE_LEFTCONTROL 29
+
+#define SCANCODE_A 30
+#define SCANCODE_S 31
+#define SCANCODE_D 32
+#define SCANCODE_F 33
+#define SCANCODE_G 34
+#define SCANCODE_H 35
+#define SCANCODE_J 36
+#define SCANCODE_K 37
+#define SCANCODE_L 38
+#define SCANCODE_SEMICOLON 39
+#define SCANCODE_APOSTROPHE 40
+#define SCANCODE_GRAVE 41
+
+#define SCANCODE_LEFTSHIFT 42
+#define SCANCODE_BACKSLASH 43
+
+#define SCANCODE_Z 44
+#define SCANCODE_X 45
+#define SCANCODE_C 46
+#define SCANCODE_V 47
+#define SCANCODE_B 48
+#define SCANCODE_N 49
+#define SCANCODE_M 50
+#define SCANCODE_COMMA 51
+#define SCANCODE_PERIOD 52
+#define SCANCODE_SLASH 53
+
+#define SCANCODE_RIGHTSHIFT 54
+#define SCANCODE_KEYPADMULTIPLY 55
+
+#define SCANCODE_LEFTALT 56
+#define SCANCODE_SPACE 57
+#define SCANCODE_CAPSLOCK 58
+
+#define SCANCODE_F1 59
+#define SCANCODE_F2 60
+#define SCANCODE_F3 61
+#define SCANCODE_F4 62
+#define SCANCODE_F5 63
+#define SCANCODE_F6 64
+#define SCANCODE_F7 65
+#define SCANCODE_F8 66
+#define SCANCODE_F9 67
+#define SCANCODE_F10 68
+
+#define SCANCODE_NUMLOCK 69
+#define SCANCODE_SCROLLLOCK 70
+
+#define SCANCODE_KEYPAD7 71
+#define SCANCODE_CURSORUPLEFT 71
+#define SCANCODE_KEYPAD8 72
+#define SCANCODE_CURSORUP 72
+#define SCANCODE_KEYPAD9 73
+#define SCANCODE_CURSORUPRIGHT 73
+#define SCANCODE_KEYPADMINUS 74
+#define SCANCODE_KEYPAD4 75
+#define SCANCODE_CURSORLEFT 75
+#define SCANCODE_KEYPAD5 76
+#define SCANCODE_KEYPAD6 77
+#define SCANCODE_CURSORRIGHT 77
+#define SCANCODE_KEYPADPLUS 78
+#define SCANCODE_KEYPAD1 79
+#define SCANCODE_CURSORDOWNLEFT 79
+#define SCANCODE_KEYPAD2 80
+#define SCANCODE_CURSORDOWN 80
+#define SCANCODE_KEYPAD3 81
+#define SCANCODE_CURSORDOWNRIGHT 81
+#define SCANCODE_KEYPAD0 82
+#define SCANCODE_KEYPADPERIOD 83
+
+#define SCANCODE_LESS 86
+
+#define SCANCODE_F11 87
+#define SCANCODE_F12 88
+
+#define SCANCODE_KEYPADENTER 96
+#define SCANCODE_RIGHTCONTROL 97
+#define SCANCODE_CONTROL 97
+#define SCANCODE_KEYPADDIVIDE 98
+#define SCANCODE_PRINTSCREEN 99
+#define SCANCODE_RIGHTALT 100
+#define SCANCODE_BREAK 101 /* Beware: is 119 */
+#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
+
+#define SCANCODE_HOME 102
+#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */
+#define SCANCODE_PAGEUP 104
+#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */
+#define SCANCODE_END 107
+#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
+#define SCANCODE_PAGEDOWN 109
+#define SCANCODE_INSERT 110
+#define SCANCODE_REMOVE 111
+
+#define SCANCODE_RIGHTWIN 126
+#define SCANCODE_LEFTWIN 125
+
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse.c b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse.c
new file mode 100644
index 0000000..52c5337
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse.c
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ggimouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse_c.h b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse_c.h
new file mode 100755
index 0000000..c0ce295
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggimouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_ggivideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.c b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.c
new file mode 100644
index 0000000..face495
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.c
@@ -0,0 +1,378 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* GGI-based SDL video driver implementation.
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <ggi/ggi.h>
+#include <ggi/gii.h>
+
+#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_ggivideo.h"
+#include "SDL_ggimouse_c.h"
+#include "SDL_ggievents_c.h"
+
+
+struct private_hwdata
+{
+ ggi_visual_t vis;
+};
+
+ggi_visual_t VIS;
+
+/* Initialization/Query functions */
+static int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GGI_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void GGI_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GGI_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* GGI driver bootstrap functions */
+
+static int GGI_Available(void)
+{
+ ggi_visual_t *vis;
+
+ vis = NULL;
+ if (ggiInit() == 0) {
+ vis = ggiOpen(NULL);
+ if (vis != NULL) {
+ ggiClose(vis);
+ }
+ }
+ return (vis != NULL);
+}
+
+static void GGI_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *GGI_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = GGI_VideoInit;
+ device->ListModes = GGI_ListModes;
+ device->SetVideoMode = GGI_SetVideoMode;
+ device->SetColors = GGI_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = GGI_VideoQuit;
+ device->AllocHWSurface = GGI_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = GGI_LockHWSurface;
+ device->UnlockHWSurface = GGI_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = GGI_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = GGI_InitOSKeymap;
+ device->PumpEvents = GGI_PumpEvents;
+
+ device->free = GGI_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap GGI_bootstrap = {
+ "ggi", "General Graphics Interface (GGI)",
+ GGI_Available, GGI_CreateDevice
+};
+
+
+static SDL_Rect video_mode;
+static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL };
+
+int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ ggi_mode mode =
+ {
+ 1,
+ { GGI_AUTO, GGI_AUTO },
+ { GGI_AUTO, GGI_AUTO },
+ { 0, 0 },
+ GT_AUTO,
+ { GGI_AUTO, GGI_AUTO }
+ };
+ struct private_hwdata *priv;
+ ggi_color pal[256], map[256];
+ const ggi_directbuffer *db;
+ int err, num_bufs;
+ ggi_pixel white, black;
+
+ priv = SDL_malloc(sizeof(struct private_hwdata));
+ if (priv == NULL)
+ {
+ SDL_SetError("Unhandled GGI mode type!\n");
+ GGI_VideoQuit(NULL);
+ }
+
+ if (ggiInit() != 0)
+ {
+ SDL_SetError("Unable to initialize GGI!\n");
+ GGI_VideoQuit(NULL);
+ }
+
+ VIS = ggiOpen(NULL);
+ if (VIS == NULL)
+ {
+ SDL_SetError("Unable to open default GGI visual!\n");
+ ggiExit();
+ GGI_VideoQuit(NULL);
+ }
+
+ ggiSetFlags(VIS, GGIFLAG_ASYNC);
+
+ /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */
+ ggiCheckMode(VIS, &mode);
+
+ /* At this point we should have a valid mode - try to set it */
+ err = ggiSetMode(VIS, &mode);
+
+ /* If we couldn't set _any_ modes, something is very wrong */
+ if (err)
+ {
+ SDL_SetError("Can't set a mode!\n");
+ ggiClose(VIS);
+ ggiExit();
+ GGI_VideoQuit(NULL);
+ }
+
+ /* Determine the current screen size */
+ this->info.current_w = mode.virt.x;
+ this->info.current_h = mode.virt.y;
+
+ /* Set a palette for palletized modes */
+ if (GT_SCHEME(mode.graphtype) == GT_PALETTE)
+ {
+ ggiSetColorfulPalette(VIS);
+ ggiGetPalette(VIS, 0, 1 << vformat->BitsPerPixel, pal);
+ }
+
+ /* Now we try to get the DirectBuffer info, which determines whether
+ * SDL can access hardware surfaces directly. */
+
+ num_bufs = ggiDBGetNumBuffers(VIS);
+
+ if (num_bufs > 0)
+ {
+ db = ggiDBGetBuffer(VIS, 0); /* Only handle one DB for now */
+
+ vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth;
+
+ vformat->Rmask = db->buffer.plb.pixelformat->red_mask;
+ vformat->Gmask = db->buffer.plb.pixelformat->green_mask;
+ vformat->Bmask = db->buffer.plb.pixelformat->blue_mask;
+
+ /* Fill in our hardware acceleration capabilities */
+
+ this->info.wm_available = 0;
+ this->info.hw_available = 1;
+ this->info.video_mem = db->buffer.plb.stride * mode.virt.y;
+ }
+
+ video_mode.x = 0;
+ video_mode.y = 0;
+ video_mode.w = mode.virt.x;
+ video_mode.h = mode.virt.y;
+ SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode;
+
+ /* We're done! */
+ return(0);
+}
+
+static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
+}
+
+/* Various screen update functions available */
+static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
+{
+ ggi_mode mode =
+ {
+ 1,
+ { GGI_AUTO, GGI_AUTO },
+ { GGI_AUTO, GGI_AUTO },
+ { 0, 0 },
+ GT_AUTO,
+ { GGI_AUTO, GGI_AUTO }
+ };
+ const ggi_directbuffer *db;
+ ggi_color pal[256];
+ int err;
+
+ fprintf(stderr, "GGI_SetVideoMode()\n");
+
+ mode.visible.x = mode.virt.x = width;
+ mode.visible.y = mode.virt.y = height;
+
+ /* Translate requested SDL bit depth into a GGI mode */
+ switch (bpp)
+ {
+ case 1: mode.graphtype = GT_1BIT; break;
+ case 2: mode.graphtype = GT_2BIT; break;
+ case 4: mode.graphtype = GT_4BIT; break;
+ case 8: mode.graphtype = GT_8BIT; break;
+ case 15: mode.graphtype = GT_15BIT; break;
+ case 16: mode.graphtype = GT_16BIT; break;
+ case 24: mode.graphtype = GT_24BIT; break;
+ case 32: mode.graphtype = GT_32BIT; break;
+ default:
+ SDL_SetError("Unknown SDL bit depth, using GT_AUTO....\n");
+ mode.graphtype = GT_AUTO;
+ }
+
+ /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */
+ ggiCheckMode(VIS, &mode);
+
+ /* At this point we should have a valid mode - try to set it */
+ err = ggiSetMode(VIS, &mode);
+
+ /* If we couldn't set _any_ modes, something is very wrong */
+ if (err)
+ {
+ SDL_SetError("Can't set a mode!\n");
+ ggiClose(VIS);
+ ggiExit();
+ GGI_VideoQuit(NULL);
+ }
+
+ /* Set a palette for palletized modes */
+ if (GT_SCHEME(mode.graphtype) == GT_PALETTE)
+ {
+ ggiSetColorfulPalette(VIS);
+ ggiGetPalette(VIS, 0, 1 << bpp, pal);
+ }
+
+ db = ggiDBGetBuffer(VIS, 0);
+
+ /* Set up the new mode framebuffer */
+ current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE);
+ current->w = mode.virt.x;
+ current->h = mode.virt.y;
+ current->pitch = db->buffer.plb.stride;
+ current->pixels = db->read;
+
+ /* Set the blit function */
+ this->UpdateRects = GGI_DirectUpdate;
+
+ /* We're done */
+ return(current);
+}
+
+static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+static int GGI_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i;
+
+/* ggiFlush(VIS); */
+
+ for (i = 0; i < numrects; i++)
+ {
+ ggiFlushRegion(VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h);
+ }
+ return;
+}
+
+int GGI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ ggi_color pal[256];
+
+ /* Set up the colormap */
+ for (i = 0; i < ncolors; i++)
+ {
+ pal[i].r = (colors[i].r << 8) | colors[i].r;
+ pal[i].g = (colors[i].g << 8) | colors[i].g;
+ pal[i].b = (colors[i].b << 8) | colors[i].b;
+ }
+
+ ggiSetPalette(VIS, firstcolor, ncolors, pal);
+
+ return 1;
+}
+
+void GGI_VideoQuit(_THIS)
+{
+}
+void GGI_FinalQuit(void)
+{
+}
diff --git a/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.h b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.h
new file mode 100644
index 0000000..014dd09
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ggi/SDL_ggivideo.h
@@ -0,0 +1,48 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_ggivideo_h
+#define _SDL_ggivideo_h
+
+#include <ggi/ggi.h>
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+#define _THIS SDL_VideoDevice *this
+
+/* Private display data */
+
+struct SDL_PrivateVideoData
+{
+ ggi_visual_t *ggivis;
+};
+
+extern ggi_visual_t VIS; /* FIXME: use the private data struct */
+
+extern int SDL_OpenKeyboard(void);
+extern void SDL_CloseKeyboard(void);
+extern int SDL_OpenMouse(void);
+extern void SDL_CloseMouse(void);
+
+#endif /* _SDL_ggivideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.c b/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.c
new file mode 100644
index 0000000..a2f3db3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.c
@@ -0,0 +1,733 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <termios.h>
+#include <ctype.h>
+
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+#include <linux/fb.h>
+
+#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_sysevents.h"
+#include "SDL_ipodvideo.h"
+
+#define _THIS SDL_VideoDevice *this
+
+static int iPod_VideoInit (_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **iPod_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *iPod_SetVideoMode (_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int iPod_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void iPod_UpdateRects (_THIS, int nrects, SDL_Rect *rects);
+static void iPod_VideoQuit (_THIS);
+static void iPod_PumpEvents (_THIS);
+
+static long iPod_GetGeneration();
+
+static int initd = 0;
+static int kbfd = -1;
+static int fbfd = -1;
+static int oldvt = -1;
+static int curvt = -1;
+static int old_kbmode = -1;
+static long generation = 0;
+static struct termios old_termios, cur_termios;
+
+FILE *dbgout;
+
+#define LCD_DATA 0x10
+#define LCD_CMD 0x08
+#define IPOD_OLD_LCD_BASE 0xc0001000
+#define IPOD_OLD_LCD_RTC 0xcf001110
+#define IPOD_NEW_LCD_BASE 0x70003000
+#define IPOD_NEW_LCD_RTC 0x60005010
+
+static unsigned long lcd_base, lcd_rtc, lcd_width, lcd_height;
+
+static long iPod_GetGeneration()
+{
+ int i;
+ char cpuinfo[256];
+ char *ptr;
+ FILE *file;
+
+ if ((file = fopen("/proc/cpuinfo", "r")) != NULL) {
+ while (fgets(cpuinfo, sizeof(cpuinfo), file) != NULL)
+ if (SDL_strncmp(cpuinfo, "Revision", 8) == 0)
+ break;
+ fclose(file);
+ }
+ for (i = 0; !isspace(cpuinfo[i]); i++);
+ for (; isspace(cpuinfo[i]); i++);
+ ptr = cpuinfo + i + 2;
+
+ return SDL_strtol(ptr, NULL, 10);
+}
+
+static int iPod_Available()
+{
+ return 1;
+}
+
+static void iPod_DeleteDevice (SDL_VideoDevice *device)
+{
+ free (device->hidden);
+ free (device);
+}
+
+void iPod_InitOSKeymap (_THIS) {}
+
+static SDL_VideoDevice *iPod_CreateDevice (int devindex)
+{
+ SDL_VideoDevice *this;
+
+ this = (SDL_VideoDevice *)SDL_malloc (sizeof(SDL_VideoDevice));
+ if (this) {
+ memset (this, 0, sizeof *this);
+ this->hidden = (struct SDL_PrivateVideoData *) SDL_malloc (sizeof(struct SDL_PrivateVideoData));
+ }
+ if (!this || !this->hidden) {
+ SDL_OutOfMemory();
+ if (this)
+ SDL_free (this);
+ return 0;
+ }
+ memset (this->hidden, 0, sizeof(struct SDL_PrivateVideoData));
+
+ generation = iPod_GetGeneration();
+
+ this->VideoInit = iPod_VideoInit;
+ this->ListModes = iPod_ListModes;
+ this->SetVideoMode = iPod_SetVideoMode;
+ this->SetColors = iPod_SetColors;
+ this->UpdateRects = iPod_UpdateRects;
+ this->VideoQuit = iPod_VideoQuit;
+ this->AllocHWSurface = 0;
+ this->CheckHWBlit = 0;
+ this->FillHWRect = 0;
+ this->SetHWColorKey = 0;
+ this->SetHWAlpha = 0;
+ this->LockHWSurface = 0;
+ this->UnlockHWSurface = 0;
+ this->FlipHWSurface = 0;
+ this->FreeHWSurface = 0;
+ this->SetCaption = 0;
+ this->SetIcon = 0;
+ this->IconifyWindow = 0;
+ this->GrabInput = 0;
+ this->GetWMInfo = 0;
+ this->InitOSKeymap = iPod_InitOSKeymap;
+ this->PumpEvents = iPod_PumpEvents;
+ this->free = iPod_DeleteDevice;
+
+ return this;
+}
+
+VideoBootStrap iPod_bootstrap = {
+ "ipod", "iPod Framebuffer Driver",
+ iPod_Available, iPod_CreateDevice
+};
+
+//--//
+
+static int iPod_VideoInit (_THIS, SDL_PixelFormat *vformat)
+{
+ if (!initd) {
+ /*** Code adapted/copied from SDL fbcon driver. ***/
+
+ static const char * const tty0[] = { "/dev/tty0", "/dev/vc/0", 0 };
+ static const char * const vcs[] = { "/dev/vc/%d", "/dev/tty%d", 0 };
+ int i, tty0_fd;
+
+ dbgout = fdopen (open ("/etc/sdlpod.log", O_WRONLY | O_SYNC | O_APPEND), "a");
+ if (dbgout) {
+ setbuf (dbgout, 0);
+ fprintf (dbgout, "--> Started SDL <--\n");
+ }
+
+ // Try to query for a free VT
+ tty0_fd = -1;
+ for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) {
+ tty0_fd = open(tty0[i], O_WRONLY, 0);
+ }
+ if ( tty0_fd < 0 ) {
+ tty0_fd = dup(0); /* Maybe stdin is a VT? */
+ }
+ ioctl(tty0_fd, VT_OPENQRY, &curvt);
+ close(tty0_fd);
+
+ tty0_fd = open("/dev/tty", O_RDWR, 0);
+ if ( tty0_fd >= 0 ) {
+ ioctl(tty0_fd, TIOCNOTTY, 0);
+ close(tty0_fd);
+ }
+
+ if ( (geteuid() == 0) && (curvt > 0) ) {
+ for ( i=0; vcs[i] && (kbfd < 0); ++i ) {
+ char vtpath[12];
+
+ SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], curvt);
+ kbfd = open(vtpath, O_RDWR);
+ }
+ }
+ if ( kbfd < 0 ) {
+ if (dbgout) fprintf (dbgout, "Couldn't open any VC\n");
+ return -1;
+ }
+ if (dbgout) fprintf (stderr, "Current VT: %d\n", curvt);
+
+ if (kbfd >= 0) {
+ /* Switch to the correct virtual terminal */
+ if ( curvt > 0 ) {
+ struct vt_stat vtstate;
+
+ if ( ioctl(kbfd, VT_GETSTATE, &vtstate) == 0 ) {
+ oldvt = vtstate.v_active;
+ }
+ if ( ioctl(kbfd, VT_ACTIVATE, curvt) == 0 ) {
+ if (dbgout) fprintf (dbgout, "Waiting for switch to this VT... ");
+ ioctl(kbfd, VT_WAITACTIVE, curvt);
+ if (dbgout) fprintf (dbgout, "done!\n");
+ }
+ }
+
+ // Set terminal input mode
+ if (tcgetattr (kbfd, &old_termios) < 0) {
+ if (dbgout) fprintf (dbgout, "Can't get termios\n");
+ return -1;
+ }
+ cur_termios = old_termios;
+ // cur_termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
+ // cur_termios.c_iflag |= (BRKINT);
+ // cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN);
+ // cur_termios.c_oflag &= ~(OPOST);
+ // cur_termios.c_oflag |= (ONOCR | ONLRET);
+ cur_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
+ cur_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
+ cur_termios.c_cc[VMIN] = 0;
+ cur_termios.c_cc[VTIME] = 0;
+
+ if (tcsetattr (kbfd, TCSAFLUSH, &cur_termios) < 0) {
+ if (dbgout) fprintf (dbgout, "Can't set termios\n");
+ return -1;
+ }
+ if (ioctl (kbfd, KDSKBMODE, K_MEDIUMRAW) < 0) {
+ if (dbgout) fprintf (dbgout, "Can't set medium-raw mode\n");
+ return -1;
+ }
+ if (ioctl (kbfd, KDSETMODE, KD_GRAPHICS) < 0) {
+ if (dbgout) fprintf (dbgout, "Can't set graphics\n");
+ return -1;
+ }
+ }
+
+ // Open the framebuffer
+ if ((fbfd = open ("/dev/fb0", O_RDWR)) < 0) {
+ if (dbgout) fprintf (dbgout, "Can't open framebuffer\n");
+ return -1;
+ } else {
+ struct fb_var_screeninfo vinfo;
+
+ if (dbgout) fprintf (dbgout, "Generation: %ld\n", generation);
+
+ if (generation >= 40000) {
+ lcd_base = IPOD_NEW_LCD_BASE;
+ } else {
+ lcd_base = IPOD_OLD_LCD_BASE;
+ }
+
+ ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo);
+ close (fbfd);
+
+ if (lcd_base == IPOD_OLD_LCD_BASE)
+ lcd_rtc = IPOD_OLD_LCD_RTC;
+ else if (lcd_base == IPOD_NEW_LCD_BASE)
+ lcd_rtc = IPOD_NEW_LCD_RTC;
+ else {
+ SDL_SetError ("Unknown iPod version");
+ return -1;
+ }
+
+ lcd_width = vinfo.xres;
+ lcd_height = vinfo.yres;
+
+ if (dbgout) fprintf (dbgout, "LCD is %dx%d\n", lcd_width, lcd_height);
+ }
+
+ fcntl (kbfd, F_SETFL, O_RDWR | O_NONBLOCK);
+
+ /* Determine the current screen size */
+ this->info.current_w = lcd_width;
+ this->info.current_h = lcd_height;
+
+ if ((generation >= 60000) && (generation < 70000)) {
+ vformat->BitsPerPixel = 16;
+ vformat->Rmask = 0xF800;
+ vformat->Gmask = 0x07E0;
+ vformat->Bmask = 0x001F;
+ } else {
+ vformat->BitsPerPixel = 8;
+ vformat->Rmask = vformat->Gmask = vformat->Bmask = 0;
+ }
+
+ initd = 1;
+ if (dbgout) fprintf (dbgout, "Initialized.\n\n");
+ }
+ return 0;
+}
+
+static SDL_Rect **iPod_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ int width, height, fd;
+ static SDL_Rect r;
+ static SDL_Rect *rs[2] = { &r, 0 };
+
+ if ((fd = open ("/dev/fb0", O_RDWR)) < 0) {
+ return 0;
+ } else {
+ struct fb_var_screeninfo vinfo;
+
+ ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo);
+ close (fbfd);
+
+ width = vinfo.xres;
+ height = vinfo.yres;
+ }
+ r.x = r.y = 0;
+ r.w = width;
+ r.h = height;
+ return rs;
+}
+
+
+static SDL_Surface *iPod_SetVideoMode (_THIS, SDL_Surface *current, int width, int height, int bpp,
+ Uint32 flags)
+{
+ Uint32 Rmask, Gmask, Bmask;
+ if (bpp > 8) {
+ Rmask = 0xF800;
+ Gmask = 0x07E0;
+ Bmask = 0x001F;
+ } else {
+ Rmask = Gmask = Bmask = 0;
+ }
+
+ if (this->hidden->buffer) SDL_free (this->hidden->buffer);
+ this->hidden->buffer = SDL_malloc (width * height * (bpp / 8));
+ if (!this->hidden->buffer) {
+ SDL_SetError ("Couldn't allocate buffer for requested mode");
+ return 0;
+ }
+
+ memset (this->hidden->buffer, 0, width * height * (bpp / 8));
+
+ if (!SDL_ReallocFormat (current, bpp, Rmask, Gmask, Bmask, 0)) {
+ SDL_SetError ("Couldn't allocate new pixel format");
+ SDL_free (this->hidden->buffer);
+ this->hidden->buffer = 0;
+ return 0;
+ }
+
+ if (bpp <= 8) {
+ int i, j;
+ for (i = 0; i < 256; i += 4) {
+ for (j = 0; j < 4; j++) {
+ current->format->palette->colors[i+j].r = 85 * j;
+ current->format->palette->colors[i+j].g = 85 * j;
+ current->format->palette->colors[i+j].b = 85 * j;
+ }
+ }
+ }
+
+ current->flags = flags & SDL_FULLSCREEN;
+ this->hidden->w = current->w = width;
+ this->hidden->h = current->h = height;
+ current->pitch = current->w * (bpp / 8);
+ current->pixels = this->hidden->buffer;
+
+ return current;
+}
+
+static int iPod_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ if (SDL_VideoSurface && SDL_VideoSurface->format && SDL_VideoSurface->format->palette) {
+ int i, j;
+ for (i = 0; i < 256; i += 4) {
+ for (j = 0; j < 4; j++) {
+ SDL_VideoSurface->format->palette->colors[i+j].r = 85 * j;
+ SDL_VideoSurface->format->palette->colors[i+j].g = 85 * j;
+ SDL_VideoSurface->format->palette->colors[i+j].b = 85 * j;
+ }
+ }
+ }
+ return 0;
+}
+
+static void iPod_VideoQuit (_THIS)
+{
+ ioctl (kbfd, KDSETMODE, KD_TEXT);
+ tcsetattr (kbfd, TCSAFLUSH, &old_termios);
+ old_kbmode = -1;
+
+ if (oldvt > 0)
+ ioctl (kbfd, VT_ACTIVATE, oldvt);
+
+ if (kbfd > 0)
+ close (kbfd);
+
+ if (dbgout) {
+ fprintf (dbgout, "<-- Ended SDL -->\n");
+ fclose (dbgout);
+ }
+
+ kbfd = -1;
+}
+
+static char iPod_SC_keymap[] = {
+ 0, /* 0 - no key */
+ '[' - 0x40, /* ESC (Ctrl+[) */
+ '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '-', '=',
+ '\b', '\t', /* Backspace, Tab (Ctrl+H,Ctrl+I) */
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
+ '\n', 0, /* Enter, Left CTRL */
+ 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
+ 0, '\\', /* left shift, backslash */
+ 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
+ 0, '*', 0, ' ', 0, /* right shift, KP mul, left alt, space, capslock */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1-10 */
+ 0, 0, /* numlock, scrollock */
+ '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', /* numeric keypad */
+ 0, 0, /* padding */
+ 0, 0, 0, /* "less" (?), F11, F12 */
+ 0, 0, 0, 0, 0, 0, 0, /* padding */
+ '\n', 0, '/', 0, 0, /* KP enter, Rctrl, Ctrl, KP div, PrtSc, RAlt */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Break, Home, Up, PgUp, Left, Right, End, Down, PgDn */
+ 0, 0, /* Ins, Del */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* padding */
+ 0, 0, /* RWin, LWin */
+ 0 /* no key */
+};
+
+
+static void iPod_keyboard()
+{
+ unsigned char keybuf[128];
+ int i, nread;
+ SDL_keysym keysym;
+ SDL_Event ev;
+
+ keysym.mod = 0;
+ keysym.scancode = 0xff;
+ memset (&ev, 0, sizeof(SDL_Event));
+
+ nread = read (kbfd, keybuf, 128);
+ for (i = 0; i < nread; i++) {
+ char ascii = iPod_SC_keymap[keybuf[i] & 0x7f];
+
+ if (dbgout) fprintf (dbgout, "Key! %02x is %c %s", keybuf[i], ascii, (keybuf[i] & 0x80)? "up" : "down");
+
+ keysym.sym = keysym.unicode = ascii;
+ ev.type = (keybuf[i] & 0x80)? SDL_KEYUP : SDL_KEYDOWN;
+ ev.key.state = 0;
+ ev.key.keysym = keysym;
+ SDL_PushEvent (&ev);
+ }
+}
+
+static void iPod_PumpEvents (_THIS)
+{
+ fd_set fdset;
+ int max_fd = 0;
+ static struct timeval zero;
+ int posted;
+
+ do {
+ posted = 0;
+
+ FD_ZERO (&fdset);
+ if (kbfd >= 0) {
+ FD_SET (kbfd, &fdset);
+ max_fd = kbfd;
+ }
+ if (dbgout) fprintf (dbgout, "Selecting");
+ if (select (max_fd + 1, &fdset, 0, 0, &zero) > 0) {
+ if (dbgout) fprintf (dbgout, " -> match!\n");
+ iPod_keyboard();
+ posted++;
+ }
+ if (dbgout) fprintf (dbgout, "\n");
+ } while (posted);
+}
+
+// enough space for 160x128x2
+static char ipod_scr[160 * (128/4)];
+
+#define outl(datum,addr) (*(volatile unsigned long *)(addr) = (datum))
+#define inl(addr) (*(volatile unsigned long *)(addr))
+
+/*** The following LCD code is taken from Linux kernel uclinux-2.4.24-uc0-ipod2,
+ file arch/armnommu/mach-ipod/fb.c. A few modifications have been made. ***/
+
+/* get current usec counter */
+static int M_timer_get_current(void)
+{
+ return inl(lcd_rtc);
+}
+
+/* check if number of useconds has past */
+static int M_timer_check(int clock_start, int usecs)
+{
+ unsigned long clock;
+ clock = inl(lcd_rtc);
+
+ if ( (clock - clock_start) >= usecs ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* wait for LCD with timeout */
+static void M_lcd_wait_write(void)
+{
+ if ( (inl(lcd_base) & 0x8000) != 0 ) {
+ int start = M_timer_get_current();
+
+ do {
+ if ( (inl(lcd_base) & (unsigned int)0x8000) == 0 )
+ break;
+ } while ( M_timer_check(start, 1000) == 0 );
+ }
+}
+
+
+/* send LCD data */
+static void M_lcd_send_data(int data_lo, int data_hi)
+{
+ M_lcd_wait_write();
+
+ outl(data_lo, lcd_base + LCD_DATA);
+
+ M_lcd_wait_write();
+
+ outl(data_hi, lcd_base + LCD_DATA);
+
+}
+
+/* send LCD command */
+static void
+M_lcd_prepare_cmd(int cmd)
+{
+ M_lcd_wait_write();
+
+ outl(0x0, lcd_base + LCD_CMD);
+
+ M_lcd_wait_write();
+
+ outl(cmd, lcd_base + LCD_CMD);
+
+}
+
+/* send LCD command and data */
+static void M_lcd_cmd_and_data(int cmd, int data_lo, int data_hi)
+{
+ M_lcd_prepare_cmd(cmd);
+
+ M_lcd_send_data(data_lo, data_hi);
+}
+
+// Copied from uW
+static void M_update_display(int sx, int sy, int mx, int my)
+{
+ int y;
+ unsigned short cursor_pos;
+
+ sx >>= 3;
+ mx >>= 3;
+
+ cursor_pos = sx + (sy << 5);
+
+ for ( y = sy; y <= my; y++ ) {
+ unsigned char *img_data;
+ int x;
+
+ /* move the cursor */
+ M_lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff);
+
+ /* setup for printing */
+ M_lcd_prepare_cmd(0x12);
+
+ img_data = ipod_scr + (sx << 1) + (y * (lcd_width/4));
+
+ /* loops up to 160 times */
+ for ( x = sx; x <= mx; x++ ) {
+ /* display eight pixels */
+ M_lcd_send_data(*(img_data + 1), *img_data);
+
+ img_data += 2;
+ }
+
+ /* update cursor pos counter */
+ cursor_pos += 0x20;
+ }
+}
+
+/* get current usec counter */
+static int C_timer_get_current(void)
+{
+ return inl(0x60005010);
+}
+
+/* check if number of useconds has past */
+static int C_timer_check(int clock_start, int usecs)
+{
+ unsigned long clock;
+ clock = inl(0x60005010);
+
+ if ( (clock - clock_start) >= usecs ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* wait for LCD with timeout */
+static void C_lcd_wait_write(void)
+{
+ if ((inl(0x70008A0C) & 0x80000000) != 0) {
+ int start = C_timer_get_current();
+
+ do {
+ if ((inl(0x70008A0C) & 0x80000000) == 0)
+ break;
+ } while (C_timer_check(start, 1000) == 0);
+ }
+}
+static void C_lcd_cmd_data(int cmd, int data)
+{
+ C_lcd_wait_write();
+ outl(cmd | 0x80000000, 0x70008A0C);
+
+ C_lcd_wait_write();
+ outl(data | 0x80000000, 0x70008A0C);
+}
+
+static void C_update_display(int sx, int sy, int mx, int my)
+{
+ int height = (my - sy) + 1;
+ int width = (mx - sx) + 1;
+
+ char *addr = SDL_VideoSurface->pixels;
+
+ if (width & 1) width++;
+
+ /* start X and Y */
+ C_lcd_cmd_data(0x12, (sy & 0xff));
+ C_lcd_cmd_data(0x13, (((SDL_VideoSurface->w - 1) - sx) & 0xff));
+
+ /* max X and Y */
+ C_lcd_cmd_data(0x15, (((sy + height) - 1) & 0xff));
+ C_lcd_cmd_data(0x16, (((((SDL_VideoSurface->w - 1) - sx) - width) + 1) & 0xff));
+
+ addr += sx + sy * SDL_VideoSurface->pitch;
+
+ while (height > 0) {
+ int h, x, y, pixels_to_write;
+
+ pixels_to_write = (width * height) * 2;
+
+ /* calculate how much we can do in one go */
+ h = height;
+ if (pixels_to_write > 64000) {
+ h = (64000/2) / width;
+ pixels_to_write = (width * h) * 2;
+ }
+
+ outl(0x10000080, 0x70008A20);
+ outl((pixels_to_write - 1) | 0xC0010000, 0x70008A24);
+ outl(0x34000000, 0x70008A20);
+
+ /* for each row */
+ for (x = 0; x < h; x++)
+ {
+ /* for each column */
+ for (y = 0; y < width; y += 2) {
+ unsigned two_pixels;
+
+ two_pixels = addr[0] | (addr[1] << 16);
+ addr += 2;
+
+ while ((inl(0x70008A20) & 0x1000000) == 0);
+
+ /* output 2 pixels */
+ outl(two_pixels, 0x70008B00);
+ }
+
+ addr += SDL_VideoSurface->w - width;
+ }
+
+ while ((inl(0x70008A20) & 0x4000000) == 0);
+
+ outl(0x0, 0x70008A24);
+
+ height = height - h;
+ }
+}
+
+// Should work with photo. However, I don't have one, so I'm not sure.
+static void iPod_UpdateRects (_THIS, int nrects, SDL_Rect *rects)
+{
+ if (SDL_VideoSurface->format->BitsPerPixel == 16) {
+ C_update_display (0, 0, lcd_width, lcd_height);
+ } else {
+ int i, y, x;
+ for (i = 0; i < nrects; i++) {
+ SDL_Rect *r = rects + i;
+ if (!r) {
+ continue;
+ }
+
+ for (y = r->y; (y < r->y + r->h) && y < lcd_height; y++) {
+ for (x = r->x; (x < r->x + r->w) && x < lcd_width; x++) {
+ ipod_scr[y*(lcd_width/4) + x/4] &= ~(3 << (2 * (x%4)));
+ ipod_scr[y*(lcd_width/4) + x/4] |=
+ (((Uint8*)(SDL_VideoSurface->pixels))[ y*SDL_VideoSurface->pitch + x ] & 3) << (2 * (x%4));
+ }
+ }
+ }
+
+ M_update_display (0, 0, lcd_width, lcd_height);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.h b/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.h
new file mode 100644
index 0000000..921eee8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ipod/SDL_ipodvideo.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* iPod SDL framebuffer driver
+ * Joshua Oreman
+ * Main header file
+ */
+
+#ifndef _SDL_ipodvideo_h
+#define _SDL_ipodvideo_h
+
+struct SDL_PrivateVideoData {
+ char *buffer;
+ int w, h;
+};
+
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_lowvideo.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_lowvideo.h
new file mode 100644
index 0000000..f3dac29
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_lowvideo.h
@@ -0,0 +1,102 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_lowvideo_h
+#define _SDL_lowvideo_h
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+#else
+#include <Quickdraw.h>
+#include <Palettes.h>
+#include <Menus.h>
+#include <DrawSprocket.h>
+#endif
+
+#if SDL_VIDEO_OPENGL
+typedef struct __AGLContextRec *AGLContext;
+#endif
+
+#include "SDL_video.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#if !TARGET_API_MAC_CARBON /* not available in OS X (or more accurately, Carbon) */
+/* Global QuickDraw data */
+extern QDGlobals *theQD;
+#endif
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ GDevice **SDL_Display;
+ WindowRef SDL_Window;
+ SDL_Rect **SDL_modelist;
+ CTabHandle SDL_CTab;
+ PaletteHandle SDL_CPal;
+
+#if TARGET_API_MAC_CARBON
+ /* For entering and leaving fullscreen mode */
+ Ptr fullscreen_ctx;
+#endif
+
+ /* The current window document style */
+ int current_style;
+
+ /* Information about the last cursor position */
+ Point last_where;
+
+ /* Information about the last keys down */
+ EventModifiers last_mods;
+ KeyMap last_keys;
+
+ /* A handle to the Apple Menu */
+ MenuRef apple_menu;
+
+ /* Information used by DrawSprocket driver */
+ struct DSpInfo *dspinfo;
+
+#if SDL_VIDEO_OPENGL
+ AGLContext appleGLContext;
+
+ void *libraryHandle;
+#endif
+};
+/* Old variable names */
+#define SDL_Display (this->hidden->SDL_Display)
+#define SDL_Window (this->hidden->SDL_Window)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define SDL_CTab (this->hidden->SDL_CTab)
+#define SDL_CPal (this->hidden->SDL_CPal)
+#define fullscreen_ctx (this->hidden->fullscreen_ctx)
+#define current_style (this->hidden->current_style)
+#define last_where (this->hidden->last_where)
+#define last_mods (this->hidden->last_mods)
+#define last_keys (this->hidden->last_keys)
+#define apple_menu (this->hidden->apple_menu)
+#define glContext (this->hidden->appleGLContext)
+
+#endif /* _SDL_lowvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents.c b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents.c
new file mode 100644
index 0000000..6e3fef2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents.c
@@ -0,0 +1,746 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <stdio.h>
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+#else
+#include <Script.h>
+#include <LowMem.h>
+#include <Devices.h>
+#include <DiskInit.h>
+#include <ToolUtils.h>
+#endif
+
+#include "SDL_events.h"
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../../events/SDL_events_c.h"
+#include "../../events/SDL_sysevents.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_macevents_c.h"
+#include "SDL_mackeys.h"
+#include "SDL_macmouse_c.h"
+
+/* Define this to be able to collapse SDL windows.
+#define USE_APPEARANCE_MANAGER
+ */
+
+/* Macintosh resource constants */
+#define mApple 128 /* Apple menu resource */
+#define iAbout 1 /* About menu item */
+
+/* Functions to handle the About menu */
+static void Mac_DoAppleMenu(_THIS, long item);
+
+/* The translation table from a macintosh key scancode to a SDL keysym */
+static SDLKey MAC_keymap[256];
+static SDL_keysym *TranslateKey(int scancode, int modifiers,
+ SDL_keysym *keysym, int pressed);
+
+/* Handle activation and deactivation -- returns whether an event was posted */
+static int Mac_HandleActivate(int activate)
+{
+ if ( activate ) {
+ /* Show the current SDL application cursor */
+ SDL_SetCursor(NULL);
+
+ /* put our mask back case it changed during context switch */
+ SetEventMask(everyEvent & ~autoKeyMask);
+ } else {
+#if TARGET_API_MAC_CARBON
+ { Cursor cursor;
+ SetCursor(GetQDGlobalsArrow(&cursor));
+ }
+#else
+ SetCursor(&theQD->arrow);
+#endif
+ if ( ! Mac_cursor_showing ) {
+ ShowCursor();
+ Mac_cursor_showing = 1;
+ }
+ }
+ return(SDL_PrivateAppActive(activate, SDL_APPINPUTFOCUS));
+}
+
+static void myGlobalToLocal(_THIS, Point *pt)
+{
+ if ( SDL_VideoSurface && !(SDL_VideoSurface->flags&SDL_FULLSCREEN) ) {
+ GrafPtr saveport;
+ GetPort(&saveport);
+#if TARGET_API_MAC_CARBON
+ SetPort(GetWindowPort(SDL_Window));
+#else
+ SetPort(SDL_Window);
+#endif
+ GlobalToLocal(pt);
+ SetPort(saveport);
+ }
+}
+
+/* The main MacOS event handler */
+static int Mac_HandleEvents(_THIS, int wait4it)
+{
+ static int mouse_button = 1;
+ int i;
+ EventRecord event;
+
+#if TARGET_API_MAC_CARBON
+ /* There's no GetOSEvent() in the Carbon API. *sigh* */
+#define cooperative_multitasking 1
+#else
+ int cooperative_multitasking;
+ /* If we're running fullscreen, we can hog the MacOS events,
+ otherwise we had better play nicely with the other apps.
+ */
+ if ( this->screen && (this->screen->flags & SDL_FULLSCREEN) ) {
+ cooperative_multitasking = 0;
+ } else {
+ cooperative_multitasking = 1;
+ }
+#endif
+
+ /* If we call WaitNextEvent(), MacOS will check other processes
+ * and allow them to run, and perform other high-level processing.
+ */
+ if ( cooperative_multitasking || wait4it ) {
+ UInt32 wait_time;
+
+ /* Are we polling or not? */
+ if ( wait4it ) {
+ wait_time = 2147483647;
+ } else {
+ wait_time = 0;
+ }
+ WaitNextEvent(everyEvent, &event, wait_time, nil);
+ } else {
+#if ! TARGET_API_MAC_CARBON
+ GetOSEvent(everyEvent, &event);
+#endif
+ }
+
+#if TARGET_API_MAC_CARBON
+ /* for some reason, event.where isn't set ? */
+ GetGlobalMouse ( &event.where );
+#endif
+
+ /* Check for mouse motion */
+ if ( (event.where.h != last_where.h) ||
+ (event.where.v != last_where.v) ) {
+ Point pt;
+ pt = last_where = event.where;
+ myGlobalToLocal(this, &pt);
+ SDL_PrivateMouseMotion(0, 0, pt.h, pt.v);
+ }
+
+ /* Check the current state of the keyboard */
+ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
+ KeyMap keys;
+ const Uint32 *keysptr = (Uint32 *) &keys;
+ const Uint32 *last_keysptr = (Uint32 *) &last_keys;
+
+ /* Check for special non-event keys */
+ if ( event.modifiers != last_mods ) {
+ static struct {
+ EventModifiers mask;
+ SDLKey key;
+ } mods[] = {
+ { alphaLock, SDLK_CAPSLOCK },
+#if 0 /* These are handled below in the GetKeys() code */
+ { cmdKey, SDLK_LMETA },
+ { shiftKey, SDLK_LSHIFT },
+ { rightShiftKey, SDLK_RSHIFT },
+ { optionKey, SDLK_LALT },
+ { rightOptionKey, SDLK_RALT },
+ { controlKey, SDLK_LCTRL },
+ { rightControlKey, SDLK_RCTRL },
+#endif /* 0 */
+ { 0, 0 }
+ };
+ SDL_keysym keysym;
+ Uint8 mode;
+ EventModifiers mod, mask;
+
+
+ /* Set up the keyboard event */
+ keysym.scancode = 0;
+ keysym.sym = SDLK_UNKNOWN;
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+
+ /* See what has changed, and generate events */
+ mod = event.modifiers;
+ for ( i=0; mods[i].mask; ++i ) {
+ mask = mods[i].mask;
+ if ( (mod&mask) != (last_mods&mask) ) {
+ keysym.sym = mods[i].key;
+ if ( (mod&mask) ||
+ (mods[i].key == SDLK_CAPSLOCK) ) {
+ mode = SDL_PRESSED;
+ } else {
+ mode = SDL_RELEASED;
+ }
+ SDL_PrivateKeyboard(mode, &keysym);
+ }
+ }
+
+ /* Save state for next time */
+ last_mods = mod;
+ }
+
+ /* Check for normal event keys, but we have to scan the
+ actual keyboard state because on Mac OS X a keydown event
+ is immediately followed by a keyup event.
+ */
+ GetKeys(keys);
+ if ( (keysptr[0] != last_keysptr[0]) ||
+ (keysptr[1] != last_keysptr[1]) ||
+ (keysptr[2] != last_keysptr[2]) ||
+ (keysptr[3] != last_keysptr[3]) ) {
+ SDL_keysym keysym;
+ int old_bit, new_bit;
+
+#ifdef DEBUG_KEYBOARD
+ fprintf(sterr, "New keys: 0x%x 0x%x 0x%x 0x%x\n",
+ new_keys[0], new_keys[1],
+ new_keys[2], new_keys[3]);
+#endif
+ for ( i=0; i<128; ++i ) {
+ old_bit = (((Uint8 *)last_keys)[i/8]>>(i%8)) & 0x01;
+ new_bit = (((Uint8 *)keys)[i/8]>>(i%8)) & 0x01;
+ if ( old_bit != new_bit ) {
+ /* Post the keyboard event */
+#ifdef DEBUG_KEYBOARD
+ fprintf(stderr,"Scancode: 0x%2.2X\n",i);
+#endif
+ SDL_PrivateKeyboard(new_bit,
+ TranslateKey(i, event.modifiers,
+ &keysym, new_bit));
+ }
+ }
+
+ /* Save state for next time */
+ last_keys[0] = keys[0];
+ last_keys[1] = keys[1];
+ last_keys[2] = keys[2];
+ last_keys[3] = keys[3];
+ }
+ }
+
+ /* Handle normal events */
+ switch (event.what) {
+ case mouseDown: {
+ WindowRef win;
+ short area;
+
+ area = FindWindow(event.where, &win);
+ /* Support switching between the SIOUX console
+ and SDL_Window by clicking in the window.
+ */
+ if ( win && (win != FrontWindow()) ) {
+ SelectWindow(win);
+ }
+ switch (area) {
+ case inMenuBar: /* Only the apple menu exists */
+ Mac_DoAppleMenu(this, MenuSelect(event.where));
+ HiliteMenu(0);
+ break;
+ case inDrag:
+#if TARGET_API_MAC_CARBON
+ DragWindow(win, event.where, NULL);
+#else
+ DragWindow(win, event.where, &theQD->screenBits.bounds);
+#endif
+ break;
+ case inGoAway:
+ if ( TrackGoAway(win, event.where) ) {
+ SDL_PrivateQuit();
+ }
+ break;
+ case inContent:
+ myGlobalToLocal(this, &event.where);
+ /* Treat command-click as right mouse button */
+ if ( event.modifiers & optionKey ) {
+ mouse_button = 2;
+ } else if ( event.modifiers & cmdKey ) {
+ mouse_button = 3;
+ } else {
+ mouse_button = 1;
+ }
+ SDL_PrivateMouseButton(SDL_PRESSED,
+ mouse_button, event.where.h, event.where.v);
+ break;
+ case inGrow: {
+ int newSize;
+
+ /* Don't allow resize if video mode isn't resizable */
+ if ( ! SDL_PublicSurface ||
+ ! (SDL_PublicSurface->flags & SDL_RESIZABLE) ) {
+ break;
+ }
+#if TARGET_API_MAC_CARBON
+ newSize = GrowWindow(win, event.where, NULL);
+#else
+ newSize = GrowWindow(win, event.where, &theQD->screenBits.bounds);
+#endif
+ if ( newSize ) {
+#if !TARGET_API_MAC_CARBON
+ EraseRect ( &theQD->screenBits.bounds );
+#endif
+ SizeWindow ( win, LoWord (newSize), HiWord (newSize), 1 );
+ SDL_PrivateResize ( LoWord (newSize), HiWord (newSize) );
+ }
+ } break;
+ case inZoomIn:
+ case inZoomOut:
+ if ( TrackBox (win, event.where, area )) {
+ Rect rect;
+#if !TARGET_API_MAC_CARBON
+ EraseRect ( &theQD->screenBits.bounds );
+#endif
+ ZoomWindow ( win, area, 0);
+ if ( area == inZoomIn ) {
+ GetWindowUserState(SDL_Window, &rect);
+ } else {
+ GetWindowStandardState(SDL_Window, &rect);
+ }
+ SDL_PrivateResize (rect.right-rect.left,
+ rect.bottom-rect.top);
+ }
+ break;
+#if TARGET_API_MAC_CARBON
+ case inCollapseBox:
+ if ( TrackBox (win, event.where, area )) {
+ if ( IsWindowCollapsable(win) ) {
+ CollapseWindow (win, !IsWindowCollapsed(win));
+ /* There should be something done like in inGrow case, but... */
+ }
+ }
+ break;
+#endif /* TARGET_API_MAC_CARBON */
+ case inSysWindow:
+#if TARGET_API_MAC_CARBON
+ /* Never happens in Carbon? */
+#else
+ SystemClick(&event, win);
+#endif
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case mouseUp: {
+ myGlobalToLocal(this, &event.where);
+ /* Release the mouse button we simulated in the last press.
+ The drawback of this methos is we cannot press more than
+ one button. However, this doesn't matter, since there is
+ only a single logical mouse button, even if you have a
+ multi-button mouse, this doesn't matter at all.
+ */
+ SDL_PrivateMouseButton(SDL_RELEASED,
+ mouse_button, event.where.h, event.where.v);
+ }
+ break;
+#if 0 /* Handled above the switch statement */
+ case keyDown: {
+ SDL_keysym keysym;
+
+ SDL_PrivateKeyboard(SDL_PRESSED,
+ TranslateKey((event.message&keyCodeMask)>>8
+ event.modifiers, &keysym, 1));
+ }
+ break;
+ case keyUp: {
+ SDL_keysym keysym;
+
+ SDL_PrivateKeyboard(SDL_RELEASED,
+ TranslateKey((event.message&keyCodeMask)>>8
+ event.modifiers, &keysym, 0));
+ }
+ break;
+#endif
+ case updateEvt: {
+ BeginUpdate(SDL_Window);
+ #if SDL_VIDEO_OPENGL
+ if (SDL_VideoSurface->flags & SDL_OPENGL)
+ SDL_GL_SwapBuffers();
+ else
+ #endif
+ if ( (SDL_VideoSurface->flags & SDL_HWSURFACE) ==
+ SDL_SWSURFACE ) {
+ SDL_UpdateRect(SDL_VideoSurface, 0, 0, 0, 0);
+ }
+ EndUpdate(SDL_Window);
+ }
+ /* If this was an update event for the SIOUX console, we return 0
+ in order to stop an endless series of updates being triggered.
+ */
+ if ( (WindowRef) event.message != SDL_Window ) {
+ return 0;
+ }
+ break;
+ case activateEvt: {
+ Mac_HandleActivate(!!(event.modifiers & activeFlag));
+ }
+ break;
+ case diskEvt: {
+#if TARGET_API_MAC_CARBON
+ /* What are we supposed to do? */;
+#else
+ if ( ((event.message>>16)&0xFFFF) != noErr ) {
+ Point spot;
+ SetPt(&spot, 0x0070, 0x0050);
+ DIBadMount(spot, event.message);
+ }
+#endif
+ }
+ break;
+ case osEvt: {
+ switch ((event.message>>24) & 0xFF) {
+#if 0 /* Handled above the switch statement */
+ case mouseMovedMessage: {
+ myGlobalToLocal(this, &event.where);
+ SDL_PrivateMouseMotion(0, 0,
+ event.where.h, event.where.v);
+ }
+ break;
+#endif /* 0 */
+ case suspendResumeMessage: {
+ Mac_HandleActivate(!!(event.message & resumeFlag));
+ }
+ break;
+ }
+ }
+ break;
+ default: {
+ ;
+ }
+ break;
+ }
+ return (event.what != nullEvent);
+}
+
+
+void Mac_PumpEvents(_THIS)
+{
+ /* Process pending MacOS events */
+ while ( Mac_HandleEvents(this, 0) ) {
+ /* Loop and check again */;
+ }
+}
+
+void Mac_InitOSKeymap(_THIS)
+{
+ const void *KCHRPtr;
+ UInt32 state;
+ UInt32 value;
+ int i;
+ int world = SDLK_WORLD_0;
+
+ /* Map the MAC keysyms */
+ for ( i=0; i<SDL_arraysize(MAC_keymap); ++i )
+ MAC_keymap[i] = SDLK_UNKNOWN;
+
+ /* Defined MAC_* constants */
+ MAC_keymap[MK_ESCAPE] = SDLK_ESCAPE;
+ MAC_keymap[MK_F1] = SDLK_F1;
+ MAC_keymap[MK_F2] = SDLK_F2;
+ MAC_keymap[MK_F3] = SDLK_F3;
+ MAC_keymap[MK_F4] = SDLK_F4;
+ MAC_keymap[MK_F5] = SDLK_F5;
+ MAC_keymap[MK_F6] = SDLK_F6;
+ MAC_keymap[MK_F7] = SDLK_F7;
+ MAC_keymap[MK_F8] = SDLK_F8;
+ MAC_keymap[MK_F9] = SDLK_F9;
+ MAC_keymap[MK_F10] = SDLK_F10;
+ MAC_keymap[MK_F11] = SDLK_F11;
+ MAC_keymap[MK_F12] = SDLK_F12;
+ MAC_keymap[MK_PRINT] = SDLK_PRINT;
+ MAC_keymap[MK_SCROLLOCK] = SDLK_SCROLLOCK;
+ MAC_keymap[MK_PAUSE] = SDLK_PAUSE;
+ MAC_keymap[MK_POWER] = SDLK_POWER;
+ MAC_keymap[MK_BACKQUOTE] = SDLK_BACKQUOTE;
+ MAC_keymap[MK_1] = SDLK_1;
+ MAC_keymap[MK_2] = SDLK_2;
+ MAC_keymap[MK_3] = SDLK_3;
+ MAC_keymap[MK_4] = SDLK_4;
+ MAC_keymap[MK_5] = SDLK_5;
+ MAC_keymap[MK_6] = SDLK_6;
+ MAC_keymap[MK_7] = SDLK_7;
+ MAC_keymap[MK_8] = SDLK_8;
+ MAC_keymap[MK_9] = SDLK_9;
+ MAC_keymap[MK_0] = SDLK_0;
+ MAC_keymap[MK_MINUS] = SDLK_MINUS;
+ MAC_keymap[MK_EQUALS] = SDLK_EQUALS;
+ MAC_keymap[MK_BACKSPACE] = SDLK_BACKSPACE;
+ MAC_keymap[MK_INSERT] = SDLK_INSERT;
+ MAC_keymap[MK_HOME] = SDLK_HOME;
+ MAC_keymap[MK_PAGEUP] = SDLK_PAGEUP;
+ MAC_keymap[MK_NUMLOCK] = SDLK_NUMLOCK;
+ MAC_keymap[MK_KP_EQUALS] = SDLK_KP_EQUALS;
+ MAC_keymap[MK_KP_DIVIDE] = SDLK_KP_DIVIDE;
+ MAC_keymap[MK_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
+ MAC_keymap[MK_TAB] = SDLK_TAB;
+ MAC_keymap[MK_q] = SDLK_q;
+ MAC_keymap[MK_w] = SDLK_w;
+ MAC_keymap[MK_e] = SDLK_e;
+ MAC_keymap[MK_r] = SDLK_r;
+ MAC_keymap[MK_t] = SDLK_t;
+ MAC_keymap[MK_y] = SDLK_y;
+ MAC_keymap[MK_u] = SDLK_u;
+ MAC_keymap[MK_i] = SDLK_i;
+ MAC_keymap[MK_o] = SDLK_o;
+ MAC_keymap[MK_p] = SDLK_p;
+ MAC_keymap[MK_LEFTBRACKET] = SDLK_LEFTBRACKET;
+ MAC_keymap[MK_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
+ MAC_keymap[MK_BACKSLASH] = SDLK_BACKSLASH;
+ MAC_keymap[MK_DELETE] = SDLK_DELETE;
+ MAC_keymap[MK_END] = SDLK_END;
+ MAC_keymap[MK_PAGEDOWN] = SDLK_PAGEDOWN;
+ MAC_keymap[MK_KP7] = SDLK_KP7;
+ MAC_keymap[MK_KP8] = SDLK_KP8;
+ MAC_keymap[MK_KP9] = SDLK_KP9;
+ MAC_keymap[MK_KP_MINUS] = SDLK_KP_MINUS;
+ MAC_keymap[MK_CAPSLOCK] = SDLK_CAPSLOCK;
+ MAC_keymap[MK_a] = SDLK_a;
+ MAC_keymap[MK_s] = SDLK_s;
+ MAC_keymap[MK_d] = SDLK_d;
+ MAC_keymap[MK_f] = SDLK_f;
+ MAC_keymap[MK_g] = SDLK_g;
+ MAC_keymap[MK_h] = SDLK_h;
+ MAC_keymap[MK_j] = SDLK_j;
+ MAC_keymap[MK_k] = SDLK_k;
+ MAC_keymap[MK_l] = SDLK_l;
+ MAC_keymap[MK_SEMICOLON] = SDLK_SEMICOLON;
+ MAC_keymap[MK_QUOTE] = SDLK_QUOTE;
+ MAC_keymap[MK_RETURN] = SDLK_RETURN;
+ MAC_keymap[MK_KP4] = SDLK_KP4;
+ MAC_keymap[MK_KP5] = SDLK_KP5;
+ MAC_keymap[MK_KP6] = SDLK_KP6;
+ MAC_keymap[MK_KP_PLUS] = SDLK_KP_PLUS;
+ MAC_keymap[MK_LSHIFT] = SDLK_LSHIFT;
+ MAC_keymap[MK_z] = SDLK_z;
+ MAC_keymap[MK_x] = SDLK_x;
+ MAC_keymap[MK_c] = SDLK_c;
+ MAC_keymap[MK_v] = SDLK_v;
+ MAC_keymap[MK_b] = SDLK_b;
+ MAC_keymap[MK_n] = SDLK_n;
+ MAC_keymap[MK_m] = SDLK_m;
+ MAC_keymap[MK_COMMA] = SDLK_COMMA;
+ MAC_keymap[MK_PERIOD] = SDLK_PERIOD;
+ MAC_keymap[MK_SLASH] = SDLK_SLASH;
+#if 0 /* These are the same as the left versions - use left by default */
+ MAC_keymap[MK_RSHIFT] = SDLK_RSHIFT;
+#endif
+ MAC_keymap[MK_UP] = SDLK_UP;
+ MAC_keymap[MK_KP1] = SDLK_KP1;
+ MAC_keymap[MK_KP2] = SDLK_KP2;
+ MAC_keymap[MK_KP3] = SDLK_KP3;
+ MAC_keymap[MK_KP_ENTER] = SDLK_KP_ENTER;
+ MAC_keymap[MK_LCTRL] = SDLK_LCTRL;
+ MAC_keymap[MK_LALT] = SDLK_LALT;
+ MAC_keymap[MK_LMETA] = SDLK_LMETA;
+ MAC_keymap[MK_SPACE] = SDLK_SPACE;
+#if 0 /* These are the same as the left versions - use left by default */
+ MAC_keymap[MK_RMETA] = SDLK_RMETA;
+ MAC_keymap[MK_RALT] = SDLK_RALT;
+ MAC_keymap[MK_RCTRL] = SDLK_RCTRL;
+#endif
+ MAC_keymap[MK_LEFT] = SDLK_LEFT;
+ MAC_keymap[MK_DOWN] = SDLK_DOWN;
+ MAC_keymap[MK_RIGHT] = SDLK_RIGHT;
+ MAC_keymap[MK_KP0] = SDLK_KP0;
+ MAC_keymap[MK_KP_PERIOD] = SDLK_KP_PERIOD;
+
+#if defined(__APPLE__) && defined(__MACH__)
+ /* Wierd, these keys are on my iBook under Mac OS X
+ Note that the left arrow keysym is the same as left ctrl!?
+ */
+ MAC_keymap[MK_IBOOK_ENTER] = SDLK_KP_ENTER;
+ MAC_keymap[MK_IBOOK_RIGHT] = SDLK_RIGHT;
+ MAC_keymap[MK_IBOOK_DOWN] = SDLK_DOWN;
+ MAC_keymap[MK_IBOOK_UP] = SDLK_UP;
+ MAC_keymap[MK_IBOOK_LEFT] = SDLK_LEFT;
+#endif /* Mac OS X */
+
+ /* Up there we setup a static scancode->keysym map. However, it will not
+ * work very well on international keyboard. Hence we now query MacOS
+ * for its own keymap to adjust our own mapping table. However, this is
+ * bascially only useful for ascii char keys. This is also the reason
+ * why we keep the static table, too.
+ */
+
+ /* Get a pointer to the systems cached KCHR */
+ KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
+ if (KCHRPtr)
+ {
+ /* Loop over all 127 possible scan codes */
+ for (i = 0; i < 0x7F; i++)
+ {
+ /* We pretend a clean start to begin with (i.e. no dead keys active */
+ state = 0;
+
+ /* Now translate the key code to a key value */
+ value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
+
+ /* If the state become 0, it was a dead key. We need to translate again,
+ passing in the new state, to get the actual key value */
+ if (state != 0)
+ value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
+
+ /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
+ if (value >= 128) /* Some non-ASCII char, map it to SDLK_WORLD_* */
+ MAC_keymap[i] = world++;
+ else if (value >= 32) /* non-control ASCII char */
+ MAC_keymap[i] = value;
+ }
+ }
+
+ /* The keypad codes are re-setup here, because the loop above cannot
+ * distinguish between a key on the keypad and a regular key. We maybe
+ * could get around this problem in another fashion: NSEvent's flags
+ * include a "NSNumericPadKeyMask" bit; we could check that and modify
+ * the symbol we return on the fly. However, this flag seems to exhibit
+ * some weird behaviour related to the num lock key
+ */
+ MAC_keymap[MK_KP0] = SDLK_KP0;
+ MAC_keymap[MK_KP1] = SDLK_KP1;
+ MAC_keymap[MK_KP2] = SDLK_KP2;
+ MAC_keymap[MK_KP3] = SDLK_KP3;
+ MAC_keymap[MK_KP4] = SDLK_KP4;
+ MAC_keymap[MK_KP5] = SDLK_KP5;
+ MAC_keymap[MK_KP6] = SDLK_KP6;
+ MAC_keymap[MK_KP7] = SDLK_KP7;
+ MAC_keymap[MK_KP8] = SDLK_KP8;
+ MAC_keymap[MK_KP9] = SDLK_KP9;
+ MAC_keymap[MK_KP_MINUS] = SDLK_KP_MINUS;
+ MAC_keymap[MK_KP_PLUS] = SDLK_KP_PLUS;
+ MAC_keymap[MK_KP_PERIOD] = SDLK_KP_PERIOD;
+ MAC_keymap[MK_KP_EQUALS] = SDLK_KP_EQUALS;
+ MAC_keymap[MK_KP_DIVIDE] = SDLK_KP_DIVIDE;
+ MAC_keymap[MK_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
+ MAC_keymap[MK_KP_ENTER] = SDLK_KP_ENTER;
+}
+
+static SDL_keysym *TranslateKey(int scancode, int modifiers,
+ SDL_keysym *keysym, int pressed)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = MAC_keymap[keysym->scancode];
+ keysym->mod = KMOD_NONE;
+ keysym->unicode = 0;
+ if ( pressed && SDL_TranslateUNICODE ) {
+ static unsigned long state = 0;
+ static Ptr keymap = nil;
+ Ptr new_keymap;
+
+ /* Get the current keyboard map resource */
+ new_keymap = (Ptr)GetScriptManagerVariable(smKCHRCache);
+ if ( new_keymap != keymap ) {
+ keymap = new_keymap;
+ state = 0;
+ }
+ keysym->unicode = KeyTranslate(keymap,
+ keysym->scancode|modifiers, &state) & 0xFFFF;
+ }
+ return(keysym);
+}
+
+void Mac_InitEvents(_THIS)
+{
+ /* Create apple menu bar */
+ apple_menu = GetMenu(mApple);
+ if ( apple_menu != nil ) {
+ AppendResMenu(apple_menu, 'DRVR');
+ InsertMenu(apple_menu, 0);
+ }
+ DrawMenuBar();
+
+ /* Get rid of spurious events at startup */
+ FlushEvents(everyEvent, 0);
+
+ /* Allow every event but keyrepeat */
+ SetEventMask(everyEvent & ~autoKeyMask);
+}
+
+void Mac_QuitEvents(_THIS)
+{
+ ClearMenuBar();
+ if ( apple_menu != nil ) {
+ ReleaseResource((char **)apple_menu);
+ }
+
+ /* Clean up pending events */
+ FlushEvents(everyEvent, 0);
+}
+
+static void Mac_DoAppleMenu(_THIS, long choice)
+{
+#if !TARGET_API_MAC_CARBON /* No Apple menu in OS X */
+ short menu, item;
+
+ item = (choice&0xFFFF);
+ choice >>= 16;
+ menu = (choice&0xFFFF);
+
+ switch (menu) {
+ case mApple: {
+ switch (item) {
+ case iAbout: {
+ /* Run the about box */;
+ }
+ break;
+ default: {
+ Str255 name;
+
+ GetMenuItemText(apple_menu, item, name);
+ OpenDeskAcc(name);
+ }
+ break;
+ }
+ }
+ break;
+ default: {
+ /* Ignore other menus */;
+ }
+ }
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+#if !TARGET_API_MAC_CARBON
+/* Since we don't initialize QuickDraw, we need to get a pointer to qd */
+struct QDGlobals *theQD = NULL;
+#endif
+
+/* Exported to the macmain code */
+void SDL_InitQuickDraw(struct QDGlobals *the_qd)
+{
+#if !TARGET_API_MAC_CARBON
+ theQD = the_qd;
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents_c.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents_c.h
new file mode 100644
index 0000000..f9a983b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macevents_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "../macrom/SDL_romvideo.h"
+
+/* Functions exported by SDL_macevents.c for the video subsystem
+*/
+extern void Mac_InitEvents(_THIS);
+extern void Mac_QuitEvents(_THIS);
+
+extern void Mac_InitOSKeymap(_THIS);
+extern void Mac_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl.c b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl.c
new file mode 100644
index 0000000..b7ded9b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl.c
@@ -0,0 +1,197 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* AGL implementation of SDL OpenGL support */
+
+#include "SDL_lowvideo.h"
+#include "SDL_macgl_c.h"
+#include "SDL_loadso.h"
+
+
+/* krat: adding OpenGL support */
+int Mac_GL_Init(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ AGLPixelFormat format;
+ int i = 0;
+ GLint attributes [ 26 ]; /* 26 is max possible in this setup */
+ GLboolean noerr;
+
+ /* load the gl driver from a default path */
+ if ( ! this->gl_config.driver_loaded ) {
+ /* no driver has been loaded, use default (ourselves) */
+ if ( Mac_GL_LoadLibrary(this, NULL) < 0 ) {
+ return(-1);
+ }
+ }
+
+ attributes[i++] = AGL_RGBA;
+ if ( this->gl_config.red_size != 0 &&
+ this->gl_config.blue_size != 0 &&
+ this->gl_config.green_size != 0 ) {
+ attributes[i++] = AGL_RED_SIZE;
+ attributes[i++] = this->gl_config.red_size;
+ attributes[i++] = AGL_GREEN_SIZE;
+ attributes[i++] = this->gl_config.green_size;
+ attributes[i++] = AGL_BLUE_SIZE;
+ attributes[i++] = this->gl_config.blue_size;
+ attributes[i++] = AGL_ALPHA_SIZE;
+ attributes[i++] = this->gl_config.alpha_size;
+ }
+ if ( this->gl_config.double_buffer ) {
+ attributes[i++] = AGL_DOUBLEBUFFER;
+ }
+ if ( this->gl_config.depth_size != 0 ) {
+ attributes[i++] = AGL_DEPTH_SIZE;
+ attributes[i++] = this->gl_config.depth_size;
+ }
+ if ( this->gl_config.stencil_size != 0 ) {
+ attributes[i++] = AGL_STENCIL_SIZE;
+ attributes[i++] = this->gl_config.stencil_size;
+ }
+ if ( this->gl_config.accum_red_size != 0 &&
+ this->gl_config.accum_blue_size != 0 &&
+ this->gl_config.accum_green_size != 0 ) {
+
+ attributes[i++] = AGL_ACCUM_RED_SIZE;
+ attributes[i++] = this->gl_config.accum_red_size;
+ attributes[i++] = AGL_ACCUM_GREEN_SIZE;
+ attributes[i++] = this->gl_config.accum_green_size;
+ attributes[i++] = AGL_ACCUM_BLUE_SIZE;
+ attributes[i++] = this->gl_config.accum_blue_size;
+ attributes[i++] = AGL_ACCUM_ALPHA_SIZE;
+ attributes[i++] = this->gl_config.accum_alpha_size;
+ }
+ if ( this->gl_config.stereo ) {
+ attributes[i++] = AGL_STEREO;
+ }
+#if defined(AGL_SAMPLE_BUFFERS_ARB) && defined(AGL_SAMPLES_ARB)
+ if ( this->gl_config.multisamplebuffers != 0 ) {
+ attributes[i++] = AGL_SAMPLE_BUFFERS_ARB;
+ attributes[i++] = this->gl_config.multisamplebuffers;
+ }
+ if ( this->gl_config.multisamplesamples != 0 ) {
+ attributes[i++] = AGL_SAMPLES_ARB;
+ attributes[i++] = this->gl_config.multisamplesamples;
+ }
+#endif
+ if ( this->gl_config.accelerated > 0 ) {
+ attributes[i++] = AGL_ACCELERATED;
+ attributes[i++] = AGL_NO_RECOVERY;
+ }
+
+ attributes[i++] = AGL_ALL_RENDERERS;
+ attributes[i] = AGL_NONE;
+
+ format = aglChoosePixelFormat(NULL, 0, attributes);
+ if ( format == NULL ) {
+ SDL_SetError("Couldn't match OpenGL desired format");
+ return(-1);
+ }
+
+ glContext = aglCreateContext(format, NULL);
+ if ( glContext == NULL ) {
+ SDL_SetError("Couldn't create OpenGL context");
+ return(-1);
+ }
+ aglDestroyPixelFormat(format);
+
+ #if TARGET_API_MAC_CARBON
+ noerr = aglSetDrawable(glContext, GetWindowPort(SDL_Window));
+ #else
+ noerr = aglSetDrawable(glContext, (AGLDrawable)SDL_Window);
+ #endif
+
+ if(!noerr) {
+ SDL_SetError("Unable to bind GL context to window");
+ return(-1);
+ }
+ return(0);
+#else
+ SDL_SetError("OpenGL support not configured");
+ return(-1);
+#endif
+}
+
+void Mac_GL_Quit(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ if ( glContext != NULL ) {
+ aglSetCurrentContext(NULL);
+ aglSetDrawable(glContext, NULL);
+ aglDestroyContext(glContext);
+ glContext = NULL;
+ }
+#endif
+}
+
+#if SDL_VIDEO_OPENGL
+
+/* Make the current context active */
+int Mac_GL_MakeCurrent(_THIS)
+{
+ int retval;
+
+ retval = 0;
+ if( ! aglSetCurrentContext(glContext) ) {
+ SDL_SetError("Unable to make GL context current");
+ retval = -1;
+ }
+ return(retval);
+}
+
+void Mac_GL_SwapBuffers(_THIS)
+{
+ aglSwapBuffers(glContext);
+}
+
+int Mac_GL_LoadLibrary(_THIS, const char *location)
+{
+ if (location == NULL)
+#if __MACH__
+ location = "/System/Library/Frameworks/OpenGL.framework/OpenGL";
+#else
+ location = "OpenGLLibrary";
+#endif
+
+ this->hidden->libraryHandle = SDL_LoadObject(location);
+
+ this->gl_config.driver_loaded = 1;
+ return (this->hidden->libraryHandle != NULL) ? 0 : -1;
+}
+
+void Mac_GL_UnloadLibrary(_THIS)
+{
+ SDL_UnloadObject(this->hidden->libraryHandle);
+
+ this->hidden->libraryHandle = NULL;
+ this->gl_config.driver_loaded = 0;
+}
+
+void* Mac_GL_GetProcAddress(_THIS, const char *proc)
+{
+ return SDL_LoadFunction( this->hidden->libraryHandle, proc );
+}
+
+#endif /* SDL_VIDEO_OPENGL */
+
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl_c.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl_c.h
new file mode 100644
index 0000000..42cd70f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macgl_c.h
@@ -0,0 +1,47 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/* AGL implementation of SDL OpenGL support */
+
+#include "SDL_config.h"
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#if __MACOSX__
+#include <AGL/agl.h> /* AGL.framework */
+#else
+#include <agl.h>
+#endif
+#endif /* SDL_VIDEO_OPENGL */
+
+/* OpenGL functions */
+extern int Mac_GL_Init(_THIS);
+extern void Mac_GL_Quit(_THIS);
+#if SDL_VIDEO_OPENGL
+extern int Mac_GL_MakeCurrent(_THIS);
+extern int Mac_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+extern void Mac_GL_SwapBuffers(_THIS);
+extern int Mac_GL_LoadLibrary(_THIS, const char *location);
+extern void Mac_GL_UnloadLibrary(_THIS);
+extern void* Mac_GL_GetProcAddress(_THIS, const char *proc);
+#endif
+
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_mackeys.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_mackeys.h
new file mode 100644
index 0000000..dfed30d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_mackeys.h
@@ -0,0 +1,140 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+/* These are the Macintosh key scancode constants -- from Inside Macintosh */
+
+#define MK_ESCAPE 0x35
+#define MK_F1 0x7A
+#define MK_F2 0x78
+#define MK_F3 0x63
+#define MK_F4 0x76
+#define MK_F5 0x60
+#define MK_F6 0x61
+#define MK_F7 0x62
+#define MK_F8 0x64
+#define MK_F9 0x65
+#define MK_F10 0x6D
+#define MK_F11 0x67
+#define MK_F12 0x6F
+#define MK_PRINT 0x69
+#define MK_SCROLLOCK 0x6B
+#define MK_PAUSE 0x71
+#define MK_POWER 0x7F
+#define MK_BACKQUOTE 0x32
+#define MK_1 0x12
+#define MK_2 0x13
+#define MK_3 0x14
+#define MK_4 0x15
+#define MK_5 0x17
+#define MK_6 0x16
+#define MK_7 0x1A
+#define MK_8 0x1C
+#define MK_9 0x19
+#define MK_0 0x1D
+#define MK_MINUS 0x1B
+#define MK_EQUALS 0x18
+#define MK_BACKSPACE 0x33
+#define MK_INSERT 0x72
+#define MK_HOME 0x73
+#define MK_PAGEUP 0x74
+#define MK_NUMLOCK 0x47
+#define MK_KP_EQUALS 0x51
+#define MK_KP_DIVIDE 0x4B
+#define MK_KP_MULTIPLY 0x43
+#define MK_TAB 0x30
+#define MK_q 0x0C
+#define MK_w 0x0D
+#define MK_e 0x0E
+#define MK_r 0x0F
+#define MK_t 0x11
+#define MK_y 0x10
+#define MK_u 0x20
+#define MK_i 0x22
+#define MK_o 0x1F
+#define MK_p 0x23
+#define MK_LEFTBRACKET 0x21
+#define MK_RIGHTBRACKET 0x1E
+#define MK_BACKSLASH 0x2A
+#define MK_DELETE 0x75
+#define MK_END 0x77
+#define MK_PAGEDOWN 0x79
+#define MK_KP7 0x59
+#define MK_KP8 0x5B
+#define MK_KP9 0x5C
+#define MK_KP_MINUS 0x4E
+#define MK_CAPSLOCK 0x39
+#define MK_a 0x00
+#define MK_s 0x01
+#define MK_d 0x02
+#define MK_f 0x03
+#define MK_g 0x05
+#define MK_h 0x04
+#define MK_j 0x26
+#define MK_k 0x28
+#define MK_l 0x25
+#define MK_SEMICOLON 0x29
+#define MK_QUOTE 0x27
+#define MK_RETURN 0x24
+#define MK_KP4 0x56
+#define MK_KP5 0x57
+#define MK_KP6 0x58
+#define MK_KP_PLUS 0x45
+#define MK_LSHIFT 0x38
+#define MK_z 0x06
+#define MK_x 0x07
+#define MK_c 0x08
+#define MK_v 0x09
+#define MK_b 0x0B
+#define MK_n 0x2D
+#define MK_m 0x2E
+#define MK_COMMA 0x2B
+#define MK_PERIOD 0x2F
+#define MK_SLASH 0x2C
+#if 0 /* These are the same as the left versions - use left by default */
+#define MK_RSHIFT 0x38
+#endif
+#define MK_UP 0x7E
+#define MK_KP1 0x53
+#define MK_KP2 0x54
+#define MK_KP3 0x55
+#define MK_KP_ENTER 0x4C
+#define MK_LCTRL 0x3B
+#define MK_LALT 0x3A
+#define MK_LMETA 0x37
+#define MK_SPACE 0x31
+#if 0 /* These are the same as the left versions - use left by default */
+#define MK_RMETA 0x37
+#define MK_RALT 0x3A
+#define MK_RCTRL 0x3B
+#endif
+#define MK_LEFT 0x7B
+#define MK_DOWN 0x7D
+#define MK_RIGHT 0x7C
+#define MK_KP0 0x52
+#define MK_KP_PERIOD 0x41
+
+/* Wierd, these keys are on my iBook under Mac OS X */
+#define MK_IBOOK_ENTER 0x34
+#define MK_IBOOK_LEFT 0x3B
+#define MK_IBOOK_RIGHT 0x3C
+#define MK_IBOOK_DOWN 0x3D
+#define MK_IBOOK_UP 0x3E
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse.c b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse.c
new file mode 100644
index 0000000..f19ad1b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse.c
@@ -0,0 +1,129 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+#else
+#include <Quickdraw.h>
+#endif
+
+/* Routines that are not supported by the Carbon API... */
+#if !TARGET_API_MAC_CARBON
+#include <CursorDevices.h>
+#endif
+
+#include "SDL_mouse.h"
+#include "SDL_macmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ Cursor curs;
+};
+
+
+void Mac_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ SDL_free(cursor);
+}
+
+WMcursor *Mac_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ int row, bytes;
+
+ /* Allocate the cursor memory */
+ cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
+ if ( cursor == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(cursor, 0, sizeof(*cursor));
+
+ if (w > 16)
+ w = 16;
+
+ if (h > 16)
+ h = 16;
+
+ bytes = (w+7)/8;
+
+ for ( row=0; row<h; ++row ) {
+ SDL_memcpy(&cursor->curs.data[row], data, bytes);
+ data += bytes;
+ }
+ for ( row=0; row<h; ++row ) {
+ SDL_memcpy(&cursor->curs.mask[row], mask, bytes);
+ mask += bytes;
+ }
+ cursor->curs.hotSpot.h = hot_x;
+ cursor->curs.hotSpot.v = hot_y;
+
+ /* That was easy. :) */
+ return(cursor);
+}
+
+int Mac_cursor_showing = 1;
+
+int Mac_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ if ( cursor == NULL ) {
+ if ( Mac_cursor_showing ) {
+ HideCursor();
+ Mac_cursor_showing = 0;
+ }
+ } else {
+ SetCursor(&cursor->curs);
+ if ( ! Mac_cursor_showing ) {
+ ShowCursor();
+ Mac_cursor_showing = 1;
+ }
+ }
+ return(1);
+}
+
+void Mac_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+#if !TARGET_API_MAC_CARBON
+ CursorDevice *cursordevice;
+
+ cursordevice = nil;
+ CursorDeviceNextDevice(&cursordevice);
+ if ( cursordevice != nil ) {
+ WindowPtr saveport;
+ Point where;
+
+ GetPort(&saveport);
+ SetPort(SDL_Window);
+ where.h = x;
+ where.v = y;
+ LocalToGlobal(&where);
+ SetPort(saveport);
+ CursorDeviceMoveTo(cursordevice, where.h, where.v);
+ }
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse_c.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse_c.h
new file mode 100644
index 0000000..18fb438
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macmouse_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "../macrom/SDL_romvideo.h"
+
+/* Functions to be exported */
+extern void Mac_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *Mac_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int Mac_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void Mac_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
+/* Data to be exported */
+extern int Mac_cursor_showing;
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm.c b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm.c
new file mode 100644
index 0000000..6f485a3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm.c
@@ -0,0 +1,442 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+#else
+#include <Windows.h>
+#include <Strings.h>
+#endif
+
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+#include <Devices.h>
+#include <Files.h>
+#include <MacTypes.h>
+#include <QDOffscreen.h>
+#include <Quickdraw.h>
+#include <Video.h>
+#endif
+
+#include "SDL_stdinc.h"
+#include "SDL_macwm_c.h"
+
+void Mac_SetCaption(_THIS, const char *title, const char *icon)
+{
+ /* Don't convert C to P string in place, because it may be read-only */
+ Str255 ptitle; /* MJS */
+ ptitle[0] = strlen (title);
+ SDL_memcpy(ptitle+1, title, ptitle[0]); /* MJS */
+ if (SDL_Window)
+ SetWTitle(SDL_Window, ptitle); /* MJS */
+}
+
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+/*
+ * ADC Gamma Ramp support...
+ *
+ * Mac Gamma Ramp code was originally from sample code provided by
+ * Apple Developer Connection, and not written specifically for SDL:
+ * "Contains: Functions to enable Mac OS device gamma adjustments using 3 channel 256 element 8 bit gamma ramps
+ * Written by: Geoff Stahl (ggs)
+ * Copyright: Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved
+ * Disclaimer: You may incorporate this sample code into your applications without
+ * restriction, though the sample code has been provided "AS IS" and the
+ * responsibility for its operation is 100% yours. However, what you are
+ * not permitted to do is to redistribute the source as "DSC Sample Code"
+ * after having made changes. If you're going to re-distribute the source,
+ * we require that you make it clear in the source that the code was
+ * descended from Apple Sample Code, but that you've made changes."
+ * (The sample code has been integrated into this file, and thus is modified from the original Apple sources.)
+ */
+
+typedef struct recDeviceGamma /* storage for device handle and gamma table */
+{
+ GDHandle hGD; /* handle to device */
+ GammaTblPtr pDeviceGamma; /* pointer to device gamma table */
+} recDeviceGamma;
+typedef recDeviceGamma * precDeviceGamma;
+
+typedef struct recSystemGamma /* storage for system devices and gamma tables */
+{
+ short numDevices; /* number of devices */
+ precDeviceGamma * devGamma; /* array of pointers to device gamma records */
+} recSystemGamma;
+typedef recSystemGamma * precSystemGamma;
+
+static Ptr CopyGammaTable (GammaTblPtr pTableGammaIn)
+{
+ GammaTblPtr pTableGammaOut = NULL;
+ short tableSize, dataWidth;
+
+ if (pTableGammaIn) /* if there is a table to copy */
+ {
+ dataWidth = (pTableGammaIn->gDataWidth + 7) / 8; /* number of bytes per entry */
+ tableSize = sizeof (GammaTbl) + pTableGammaIn->gFormulaSize +
+ (pTableGammaIn->gChanCnt * pTableGammaIn->gDataCnt * dataWidth);
+ pTableGammaOut = (GammaTblPtr) NewPtr (tableSize); /* allocate new table */
+ if (pTableGammaOut)
+ BlockMove( (Ptr)pTableGammaIn, (Ptr)pTableGammaOut, tableSize); /* move everything */
+ }
+ return (Ptr)pTableGammaOut; /* return whatever we allocated, could be NULL */
+}
+
+static OSErr GetGammaTable (GDHandle hGD, GammaTblPtr * ppTableGammaOut)
+{
+ VDGammaRecord DeviceGammaRec;
+ CntrlParam cParam;
+ OSErr err;
+
+ cParam.ioCompletion = NULL; /* set up control params */
+ cParam.ioNamePtr = NULL;
+ cParam.ioVRefNum = 0;
+ cParam.ioCRefNum = (**hGD).gdRefNum;
+ cParam.csCode = cscGetGamma; /* Get Gamma commnd to device */
+ *(Ptr *)cParam.csParam = (Ptr) &DeviceGammaRec; /* record for gamma */
+
+ err = PBStatusSync( (ParmBlkPtr)&cParam ); /* get gamma */
+
+ *ppTableGammaOut = (GammaTblPtr)(DeviceGammaRec.csGTable); /* pull table out of record */
+
+ return err;
+}
+
+static Ptr GetDeviceGamma (GDHandle hGD)
+{
+ GammaTblPtr pTableGammaDevice = NULL;
+ GammaTblPtr pTableGammaReturn = NULL;
+ OSErr err;
+
+ err = GetGammaTable (hGD, &pTableGammaDevice); /* get a pointer to the devices table */
+ if ((noErr == err) && pTableGammaDevice) /* if succesful */
+ pTableGammaReturn = (GammaTblPtr) CopyGammaTable (pTableGammaDevice); /* copy to global */
+
+ return (Ptr) pTableGammaReturn;
+}
+
+static void DisposeGammaTable (Ptr pGamma)
+{
+ if (pGamma)
+ DisposePtr((Ptr) pGamma); /* get rid of it */
+}
+
+static void DisposeSystemGammas (Ptr* ppSystemGammas)
+{
+ precSystemGamma pSysGammaIn;
+ if (ppSystemGammas)
+ {
+ pSysGammaIn = (precSystemGamma) *ppSystemGammas;
+ if (pSysGammaIn)
+ {
+ short i;
+ for (i = 0; i < pSysGammaIn->numDevices; i++) /* for all devices */
+ if (pSysGammaIn->devGamma [i]) /* if pointer is valid */
+ {
+ DisposeGammaTable ((Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma); /* dump gamma table */
+ DisposePtr ((Ptr) pSysGammaIn->devGamma [i]); /* dump device info */
+ }
+ DisposePtr ((Ptr) pSysGammaIn->devGamma); /* dump device pointer array */
+ DisposePtr ((Ptr) pSysGammaIn); /* dump system structure */
+ *ppSystemGammas = NULL;
+ }
+ }
+}
+
+static Boolean GetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp)
+{
+ GammaTblPtr pTableGammaTemp = NULL;
+ long indexChan, indexEntry;
+ OSErr err;
+
+ if (pRamp) /* ensure pRamp is allocated */
+ {
+ err = GetGammaTable (hGD, &pTableGammaTemp); /* get a pointer to the current gamma */
+ if ((noErr == err) && pTableGammaTemp) /* if successful */
+ {
+ /* fill ramp */
+ unsigned char * pEntry = (unsigned char *) &pTableGammaTemp->gFormulaData + pTableGammaTemp->gFormulaSize; /* base of table */
+ short bytesPerEntry = (pTableGammaTemp->gDataWidth + 7) / 8; /* size, in bytes, of the device table entries */
+ short shiftRightValue = pTableGammaTemp->gDataWidth - 8; /* number of right shifts device -> ramp */
+ short channels = pTableGammaTemp->gChanCnt;
+ short entries = pTableGammaTemp->gDataCnt;
+ if (3 == channels) /* RGB format */
+ { /* note, this will create runs of entries if dest. is bigger (not linear interpolate) */
+ for (indexChan = 0; indexChan < channels; indexChan++)
+ for (indexEntry = 0; indexEntry < 256; indexEntry++)
+ *((unsigned char *) pRamp + (indexChan * 256) + indexEntry) =
+ *(pEntry + indexChan * entries * bytesPerEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue;
+ }
+ else /* single channel format */
+ {
+ for (indexChan = 0; indexChan < 768; indexChan += 256) /* repeat for all 3 channels (step by ramp size) */
+ for (indexEntry = 0; indexEntry < 256; indexEntry++) /* for all entries set vramp value */
+ *((unsigned char *) pRamp + indexChan + indexEntry) =
+ *(pEntry + indexEntry * entries * bytesPerEntry / 256) >> shiftRightValue;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+static Ptr GetSystemGammas (void)
+{
+ precSystemGamma pSysGammaOut; /* return pointer to system device gamma info */
+ short devCount = 0; /* number of devices attached */
+ Boolean fail = false;
+ GDHandle hGDevice;
+
+ pSysGammaOut = (precSystemGamma) NewPtr (sizeof (recSystemGamma)); /* allocate for structure */
+
+ hGDevice = GetDeviceList (); /* top of device list */
+ do /* iterate */
+ {
+ devCount++; /* count devices */
+ hGDevice = GetNextDevice (hGDevice); /* next device */
+ } while (hGDevice);
+
+ pSysGammaOut->devGamma = (precDeviceGamma *) NewPtr (sizeof (precDeviceGamma) * devCount); /* allocate for array of pointers to device records */
+ if (pSysGammaOut)
+ {
+ pSysGammaOut->numDevices = devCount; /* stuff count */
+
+ devCount = 0; /* reset iteration */
+ hGDevice = GetDeviceList ();
+ do
+ {
+ pSysGammaOut->devGamma [devCount] = (precDeviceGamma) NewPtr (sizeof (recDeviceGamma)); /* new device record */
+ if (pSysGammaOut->devGamma [devCount]) /* if we actually allocated memory */
+ {
+ pSysGammaOut->devGamma [devCount]->hGD = hGDevice; /* stuff handle */
+ pSysGammaOut->devGamma [devCount]->pDeviceGamma = (GammaTblPtr)GetDeviceGamma (hGDevice); /* copy gamma table */
+ }
+ else /* otherwise dump record on exit */
+ fail = true;
+ devCount++; /* next device */
+ hGDevice = GetNextDevice (hGDevice);
+ } while (hGDevice);
+ }
+ if (!fail) /* if we did not fail */
+ return (Ptr) pSysGammaOut; /* return pointer to structure */
+ else
+ {
+ DisposeSystemGammas ((Ptr *) &pSysGammaOut); /* otherwise dump the current structures (dispose does error checking) */
+ return NULL; /* could not complete */
+ }
+}
+
+static void RestoreDeviceGamma (GDHandle hGD, Ptr pGammaTable)
+{
+ VDSetEntryRecord setEntriesRec;
+ VDGammaRecord gameRecRestore;
+ CTabHandle hCTabDeviceColors;
+ Ptr csPtr;
+ OSErr err = noErr;
+
+ if (pGammaTable) /* if we have a table to restore */
+ {
+ gameRecRestore.csGTable = pGammaTable; /* setup restore record */
+ csPtr = (Ptr) &gameRecRestore;
+ err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma */
+
+ if ((noErr == err) && (8 == (**(**hGD).gdPMap).pixelSize)) /* if successful and on an 8 bit device */
+ {
+ hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */
+ setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
+ setEntriesRec.csStart = 0;
+ setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
+ csPtr = (Ptr) &setEntriesRec;
+
+ err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */
+ }
+ }
+}
+
+static void RestoreSystemGammas (Ptr pSystemGammas)
+{
+ short i;
+ precSystemGamma pSysGammaIn = (precSystemGamma) pSystemGammas;
+ if (pSysGammaIn)
+ for (i = 0; i < pSysGammaIn->numDevices; i++) /* for all devices */
+ RestoreDeviceGamma (pSysGammaIn->devGamma [i]->hGD, (Ptr) pSysGammaIn->devGamma [i]->pDeviceGamma); /* restore gamma */
+}
+
+static Ptr CreateEmptyGammaTable (short channels, short entries, short bits)
+{
+ GammaTblPtr pTableGammaOut = NULL;
+ short tableSize, dataWidth;
+
+ dataWidth = (bits + 7) / 8; /* number of bytes per entry */
+ tableSize = sizeof (GammaTbl) + (channels * entries * dataWidth);
+ pTableGammaOut = (GammaTblPtr) NewPtrClear (tableSize); /* allocate new tabel */
+
+ if (pTableGammaOut) /* if we successfully allocated */
+ {
+ pTableGammaOut->gVersion = 0; /* set parameters based on input */
+ pTableGammaOut->gType = 0;
+ pTableGammaOut->gFormulaSize = 0;
+ pTableGammaOut->gChanCnt = channels;
+ pTableGammaOut->gDataCnt = entries;
+ pTableGammaOut->gDataWidth = bits;
+ }
+ return (Ptr)pTableGammaOut; /* return whatever we allocated */
+}
+
+static Boolean SetDeviceGammaRampGD (GDHandle hGD, Ptr pRamp)
+{
+ VDSetEntryRecord setEntriesRec;
+ VDGammaRecord gameRecRestore;
+ GammaTblPtr pTableGammaNew;
+ GammaTblPtr pTableGammaCurrent = NULL;
+ CTabHandle hCTabDeviceColors;
+ Ptr csPtr;
+ OSErr err;
+ short dataBits, entries, channels = 3; /* force three channels in the gamma table */
+
+ if (pRamp) /* ensure pRamp is allocated */
+ {
+ err= GetGammaTable (hGD, &pTableGammaCurrent); /* get pointer to current table */
+ if ((noErr == err) && pTableGammaCurrent)
+ {
+ dataBits = pTableGammaCurrent->gDataWidth; /* table must have same data width */
+ entries = pTableGammaCurrent->gDataCnt; /* table must be same size */
+ pTableGammaNew = (GammaTblPtr) CreateEmptyGammaTable (channels, entries, dataBits); /* our new table */
+ if (pTableGammaNew) /* if successful fill table */
+ {
+ unsigned char * pGammaBase = (unsigned char *) &pTableGammaNew->gFormulaData + pTableGammaNew->gFormulaSize; /* base of table */
+ if ((256 == entries) && (8 == dataBits)) /* simple case: direct mapping */
+ BlockMove ((Ptr)pRamp, (Ptr)pGammaBase, channels * entries); /* move everything */
+ else /* tough case handle entry, channel and data size disparities */
+ {
+ short indexChan, indexEntry;
+ short bytesPerEntry = (dataBits + 7) / 8; /* size, in bytes, of the device table entries */
+ short shiftRightValue = 8 - dataBits; /* number of right shifts ramp -> device */
+ shiftRightValue += ((bytesPerEntry - 1) * 8); /* multibyte entries and the need to map a byte at a time most sig. to least sig. */
+ for (indexChan = 0; indexChan < channels; indexChan++) /* for all the channels */
+ for (indexEntry = 0; indexEntry < entries; indexEntry++) /* for all the entries */
+ {
+ short currentShift = shiftRightValue; /* reset current bit shift */
+ long temp = *((unsigned char *)pRamp + (indexChan << 8) + (indexEntry << 8) / entries); /* get data from ramp */
+ short indexByte;
+ for (indexByte = 0; indexByte < bytesPerEntry; indexByte++) /* for all bytes */
+ {
+ if (currentShift < 0) /* shift data correctly for current byte */
+ *(pGammaBase++) = temp << -currentShift;
+ else
+ *(pGammaBase++) = temp >> currentShift;
+ currentShift -= 8; /* increment shift to align to next less sig. byte */
+ }
+ }
+ }
+
+ /* set gamma */
+ gameRecRestore.csGTable = (Ptr) pTableGammaNew; /* setup restore record */
+ csPtr = (Ptr) &gameRecRestore;
+ err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma (note, display drivers may delay returning from this until VBL) */
+
+ if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err)) /* if successful and on an 8 bit device */
+ {
+ hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */
+ setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
+ setEntriesRec.csStart = 0;
+ setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
+ csPtr = (Ptr) &setEntriesRec;
+ err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */
+ }
+ DisposeGammaTable ((Ptr) pTableGammaNew); /* dump table */
+ if (noErr == err)
+ return true;
+ }
+ }
+ }
+ else /* set NULL gamma -> results in linear map */
+ {
+ gameRecRestore.csGTable = (Ptr) NULL; /* setup restore record */
+ csPtr = (Ptr) &gameRecRestore;
+ err = Control((**hGD).gdRefNum, cscSetGamma, (Ptr) &csPtr); /* restore gamma */
+
+ if ((8 == (**(**hGD).gdPMap).pixelSize) && (noErr == err)) /* if successful and on an 8 bit device */
+ {
+ hCTabDeviceColors = (**(**hGD).gdPMap).pmTable; /* do SetEntries to force CLUT update */
+ setEntriesRec.csTable = (ColorSpec *) &(**hCTabDeviceColors).ctTable;
+ setEntriesRec.csStart = 0;
+ setEntriesRec.csCount = (**hCTabDeviceColors).ctSize;
+ csPtr = (Ptr) &setEntriesRec;
+ err = Control((**hGD).gdRefNum, cscSetEntries, (Ptr) &csPtr); /* SetEntries in CLUT */
+ }
+ if (noErr == err)
+ return true;
+ }
+ return false; /* memory allocation or device control failed if we get here */
+}
+
+/* end of ADC Gamma Ramp support code... */
+
+static Ptr systemGammaPtr;
+
+void Mac_QuitGamma(_THIS)
+{
+ if (systemGammaPtr)
+ {
+ RestoreSystemGammas(systemGammaPtr);
+ DisposeSystemGammas(&systemGammaPtr);
+ }
+}
+
+static unsigned char shiftedRamp[3 * 256];
+
+int Mac_SetGammaRamp(_THIS, Uint16 *ramp)
+{
+ int i;
+ if (!systemGammaPtr)
+ systemGammaPtr = GetSystemGammas();
+ for (i = 0; i < 3 * 256; i++)
+ {
+ shiftedRamp[i] = ramp[i] >> 8;
+ }
+
+ if (SetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp))
+ return 0;
+ else
+ return -1;
+}
+
+int Mac_GetGammaRamp(_THIS, Uint16 *ramp)
+{
+ if (GetDeviceGammaRampGD(GetMainDevice(), (Ptr) shiftedRamp))
+ {
+ int i;
+ for (i = 0; i < 3 * 256; i++)
+ {
+ ramp[i] = shiftedRamp[i] << 8;
+ }
+ return 0;
+ }
+ else
+ return -1;
+}
+
+#endif /* SDL_MACCLASSIC_GAMMA_SUPPORT */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm_c.h b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm_c.h
new file mode 100644
index 0000000..a0554d1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/maccommon/SDL_macwm_c.h
@@ -0,0 +1,41 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "../macrom/SDL_romvideo.h"
+
+/* Functions to be exported */
+extern void Mac_SetCaption(_THIS, const char *title, const char *icon);
+
+/*
+ * There's no Carbonized gamma support in Mac OS X, since PBStatusSync() and
+ * Control() aren't supported in OS X's Carbonlib. Use the Quartz driver
+ * instead.
+ */
+#define SDL_MACCLASSIC_GAMMA_SUPPORT ((defined(__APPLE__) && defined(__MACH__)) == 0)
+
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+extern void Mac_QuitGamma(_THIS);
+extern int Mac_SetGammaRamp(_THIS, Uint16 *ramp);
+extern int Mac_GetGammaRamp(_THIS, Uint16 *ramp);
+#endif
+
diff --git a/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.c b/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.c
new file mode 100644
index 0000000..aa31127
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.c
@@ -0,0 +1,1422 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Written by Darrell Walisser <dwaliss1@purdue.edu>
+
+ Implementation notes ----------------------------------------------------------------------
+
+ A bit on GWorlds in VRAM from technote 1182:
+
+ There are two important things to note about GWorld's allocated in
+ VRAM. First, the base address retrieved through GetPixBaseAddr or
+ read directly from the PixMap structure can become invalid anytime
+ memory is allocated in VRAM. This can occur either by explicit
+ allocations, such as calls to NewGWorld, or by implicit ones, such as
+ those associated with the internal texture allocation of OpenGL. The
+ stored pixel images themselves will still be valid but may have been
+ moved in VRAM, thus rendering any stored base addresses invalid.
+ You should never store an image's base address for longer than is
+ necessary and especially never across calls to NewGWorld or
+ texture-creation routines.
+
+ Secondly, an offscreen pixel image allocated in VRAM can be
+ purged at system task time by the display driver. This means any
+ time your application yields time such by calling WaitNextEvent or
+ SystemTask you can lose your VRAM GWorld contents. While this
+ happens infrequently, usually associated with display resolution or
+ pixel depth changes you must code for this eventuality. This purge
+ can occur whether or not the GWorld is locked or not. A return value
+ of false from LockPixels, a NULL return value from GetPixBaseAddr
+ or NULL in the baseAddr field of the PixMap mean that the pixel
+ image has been purged. To reallocate it you can either call
+ UpdateGWorld or Dispose your current GWorld through
+ DisposeGWorld and reallocate it via NewGWorld. Either way you must
+ then rebuild the pixel image.
+
+------------------------------------------------------------------------------------
+
+ Currently, I don't account for (1). In my testing, NewGWorld never invalidated
+ other existing GWorlds in VRAM. However, I do have protection for (2).
+ Namely, I am using GetOSEvent() instead of WaitNextEvent() so that there are no
+ context switches (the app hogs the CPU). Eventually a book-keeping system should
+ be coded to take care of (1) and (2).
+
+------------------------------------------------------------------------------------
+
+ System requirements (* denotes optional):
+
+ 1. DrawSprocket 1.7.3
+ 2. *MacOS 9 or later (but *not* Mac OS X) for hardware accelerated blit / fill
+ 3. *May also require certain graphics hardware for (2). I trust that all Apple OEM
+ hardware will work. Third party accelerators may work if they have QuickDraw
+ acceleration in the drivers and the drivers have been updated for OS 9. The current
+ Voodoo 3 drivers (1.0b12) do not work.
+
+ Coding suggestions:
+
+ 1. Use SDL_UpdateRects !
+
+ If no QuickDraw acceleration is present, double-buffered surfaces will use a back buffer
+ in System memory. I recommend you use SDL_UpdateRects with double-buffered surfaces
+ for best performance on these cards, since the overhead is nearly zero for VRAM back buffer.
+
+ 2. Load most-resident surfaces first.
+
+ If you fill up VRAM or AGP memory, there is no contingency for purging to make room for the next one.
+ Therefore, you should load the surfaces you plan to use the most frequently first.
+ Sooner or later, I will code LRU replacement to help this.
+
+ TODO:
+ Some kind of posterized mode for resolutions < 640x480.
+ Window support / fullscreen toggle.
+ Figure out how much VRAM is available. Put in video->info->video_mem.
+ Track VRAM usage.
+
+ BUGS:
+ I can't create a hardware surface the same size as the screen?! How to fix?
+
+
+
+ COMPILE OPTIONS:
+
+ DSP_TRY_CC_AND_AA - Define if you want to try HWA color-key and alpha blitters
+ HW color-key blitting gives substantial improvements,
+ but hw alpha is neck-and-neck with SDL's soft bitter.
+
+ DSP_NO_SYNC_VBL - Define for HWA double-buffered surfaces: don't sync
+ pseudo-flip to monitor redraw.
+
+ DSP_NO_SYNC_OPENGL - Define for OpenGL surfaces: don't sync buffer swap. Synching buffer
+ swap may result in reduced performance, but can eliminate some
+ tearing artifacts.
+ CHANGELOG:
+ 09/17/00 Lots of little tweaks. Build modelist in reverse order so largest contexts
+ list first. Compared various methods with ROM methods and fixed rez switch
+ crashing bug in GL Tron. (Woohoo!)
+*/
+
+#define DSP_TRY_CC_AND_AA
+
+/* #define DSP_NO_SYNC_VBL */
+
+#define DSP_NO_SYNC_OPENGL
+
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#include <DrawSprocket/DrawSprocket.h>
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+#include <DrawSprocket.h>
+#else
+#include <LowMem.h>
+#include <Gestalt.h>
+#include <Devices.h>
+#include <DiskInit.h>
+#include <QDOffscreen.h>
+#include <DrawSprocket.h>
+#endif
+
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_blit.h"
+#include "../SDL_pixels_c.h"
+#include "SDL_dspvideo.h"
+#include "../maccommon/SDL_macgl_c.h"
+#include "../maccommon/SDL_macwm_c.h"
+#include "../maccommon/SDL_macmouse_c.h"
+#include "../maccommon/SDL_macevents_c.h"
+
+/* Initialization/Query functions */
+static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DSp_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DSp_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static int DSp_CreatePalette(_THIS);
+static int DSp_DestroyPalette(_THIS);
+static void DSp_VideoQuit(_THIS);
+
+static int DSp_GetMainDevice (_THIS, GDHandle *device);
+static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat);
+static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);
+static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);
+
+/* Hardware surface functions */
+static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha);
+static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
+static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height);
+static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DSp_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface);
+static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface);
+static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest);
+static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
+
+#if SDL_VIDEO_OPENGL
+ static void DSp_GL_SwapBuffers (_THIS);
+#endif
+
+#if ! TARGET_API_MAC_CARBON
+
+ #define GetPortPixRowBytes(x) ( (*(x->portPixMap))->rowBytes )
+ #define GetGDevPixMap(x) ((**(x)).gdPMap)
+ #define GetPortPixMap(x) ((*(x)).portPixMap)
+
+ #define GetPixDepth(y) ((**(y)).pixelSize)
+ //#define GetPixRowBytes(y) ((**(y)).rowBytes)
+ //#define GetPixBaseAddr(y) ((**(y)).baseAddr)
+ #define GetPixCTab(y) ((**(y)).pmTable)
+ #define GetPortBitMapForCopyBits(x) (&(((GrafPtr)(x))->portBits))
+
+#else
+ #define GetPortPixRowBytes(x) (GetPixRowBytes(GetPortPixMap(x)) )
+ #define GetGDevPixMap(x) ((**(x)).gdPMap)
+
+#endif
+
+typedef struct private_hwdata {
+
+ GWorldPtr offscreen; // offscreen gworld in VRAM or AGP
+
+ #ifdef DSP_TRY_CC_AND_AA
+ GWorldPtr mask; // transparent mask
+ RGBColor alpha; // alpha color
+ RGBColor trans; // transparent color
+ #endif
+
+} private_hwdata;
+
+typedef private_hwdata private_swdata ; /* have same fields */
+
+/* Macintosh toolbox driver bootstrap functions */
+
+static int DSp_Available(void)
+{
+ /* Check for DrawSprocket */
+#if ! TARGET_API_MAC_OSX
+ /* This check is only meaningful if you weak-link DrawSprocketLib */
+ return ((Ptr)DSpStartup != (Ptr)kUnresolvedCFragSymbolAddress);
+#else
+ return 1; // DrawSprocket.framework doesn't have it all, but it's there
+#endif
+}
+
+static void DSp_DeleteDevice(SDL_VideoDevice *device)
+{
+ /* -dw- taking no chances with null pointers */
+ if (device) {
+
+ if (device->hidden) {
+
+ if (device->hidden->dspinfo)
+ SDL_free(device->hidden->dspinfo);
+
+ SDL_free(device->hidden);
+ }
+ SDL_free(device);
+ }
+}
+
+static SDL_VideoDevice *DSp_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, sizeof (*device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ if (device->hidden)
+ SDL_memset(device->hidden, 0, sizeof ( *(device->hidden) ) );
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+
+ if ( device ) {
+
+ if (device->hidden)
+ SDL_free(device->hidden);
+
+ SDL_free(device);
+ }
+
+ return(NULL);
+ }
+
+ /* Allocate DrawSprocket information */
+ device->hidden->dspinfo = (struct DSpInfo *)SDL_malloc(
+ (sizeof *device->hidden->dspinfo));
+ if ( device->hidden->dspinfo == NULL ) {
+ SDL_OutOfMemory();
+ SDL_free(device->hidden);
+ SDL_free(device);
+ return(0);
+ }
+ SDL_memset(device->hidden->dspinfo, 0, (sizeof *device->hidden->dspinfo));
+
+ /* Set the function pointers */
+ device->VideoInit = DSp_VideoInit;
+ device->ListModes = DSp_ListModes;
+ device->SetVideoMode = DSp_SetVideoMode;
+ device->SetColors = DSp_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = DSp_VideoQuit;
+ device->AllocHWSurface = DSp_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = DSp_LockHWSurface;
+ device->UnlockHWSurface = DSp_UnlockHWSurface;
+ device->FlipHWSurface = DSp_FlipHWSurface;
+ device->FreeHWSurface = DSp_FreeHWSurface;
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+ device->SetGammaRamp = Mac_SetGammaRamp;
+ device->GetGammaRamp = Mac_GetGammaRamp;
+#endif
+#if SDL_VIDEO_OPENGL
+ device->GL_MakeCurrent = Mac_GL_MakeCurrent;
+ device->GL_SwapBuffers = DSp_GL_SwapBuffers;
+ device->GL_LoadLibrary = Mac_GL_LoadLibrary;
+ device->GL_GetProcAddress = Mac_GL_GetProcAddress;
+#endif
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = Mac_FreeWMCursor;
+ device->CreateWMCursor = Mac_CreateWMCursor;
+ device->ShowWMCursor = Mac_ShowWMCursor;
+ device->WarpWMCursor = Mac_WarpWMCursor;
+ device->InitOSKeymap = Mac_InitOSKeymap;
+ device->PumpEvents = Mac_PumpEvents;
+
+ device->GrabInput = NULL;
+ device->CheckMouseMode = NULL;
+
+ device->free = DSp_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap DSp_bootstrap = {
+ "DSp", "MacOS DrawSprocket",
+ DSp_Available, DSp_CreateDevice
+};
+
+/* Use DSp/Display Manager to build mode list for given screen */
+static SDL_Rect** DSp_BuildModeList (const GDHandle gDevice, int *displayWidth, int *displayHeight)
+{
+ DSpContextAttributes attributes;
+ DSpContextReference context;
+ DisplayIDType displayID;
+ SDL_Rect temp_list [16];
+ SDL_Rect **mode_list;
+ int width, height, i, j;
+
+ #if TARGET_API_MAC_OSX
+
+ displayID = 0;
+
+ #else
+ /* Ask Display Manager for integer id of screen device */
+ if ( DMGetDisplayIDByGDevice (gDevice, &displayID, SDL_TRUE) != noErr ) {
+ return NULL;
+ }
+ #endif
+ /* Get the first possible DSp context on this device */
+ if ( DSpGetFirstContext (displayID, &context) != noErr ) {
+ return NULL;
+ }
+
+ if ( DSpContext_GetAttributes (context, &attributes) != noErr )
+ return NULL;
+
+ *displayWidth = attributes.displayWidth;
+ *displayHeight = attributes.displayHeight;
+
+ for ( i = 0; i < SDL_arraysize(temp_list); i++ ) {
+ width = attributes.displayWidth;
+ height = attributes.displayHeight;
+
+ temp_list [i].x = 0 | attributes.displayBestDepth;
+ temp_list [i].y = 0;
+ temp_list [i].w = width;
+ temp_list [i].h = height;
+
+ /* DSp will report many different contexts with the same width and height. */
+ /* They will differ in bit depth and refresh rate. */
+ /* We will ignore them until we reach one with a different width/height */
+ /* When there are no more contexts to look at, we will quit building the list*/
+ while ( width == attributes.displayWidth && height == attributes.displayHeight ) {
+
+ OSStatus err = DSpGetNextContext (context, &context);
+ if (err != noErr)
+ if (err == kDSpContextNotFoundErr)
+ goto done;
+ else
+ return NULL;
+
+ if ( DSpContext_GetAttributes (context, &attributes) != noErr )
+ return NULL;
+
+ temp_list [i].x |= attributes.displayBestDepth;
+ }
+ }
+done:
+ i++; /* i was not incremented before kicking out of the loop */
+
+ mode_list = (SDL_Rect**) SDL_malloc (sizeof (SDL_Rect*) * (i+1));
+ if (mode_list) {
+
+ /* -dw- new stuff: build in reverse order so largest sizes list first */
+ for (j = i-1; j >= 0; j--) {
+ mode_list [j] = (SDL_Rect*) SDL_malloc (sizeof (SDL_Rect));
+ if (mode_list [j])
+ SDL_memcpy (mode_list [j], &(temp_list [j]), sizeof (SDL_Rect));
+ else {
+ SDL_OutOfMemory ();
+ return NULL;
+ }
+ }
+ mode_list [i] = NULL; /* append null to the end */
+ }
+ else {
+ SDL_OutOfMemory ();
+ return NULL;
+ }
+
+ return mode_list;
+}
+
+static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat)
+{
+ /*
+ VRAM GWorlds are only available on OS 9 or later.
+ Even with OS 9, some display drivers won't support it,
+ so we create a test GWorld and check for errors.
+ */
+
+ long versionSystem;
+
+ dsp_vram_available = SDL_FALSE;
+ dsp_agp_available = SDL_FALSE;
+
+ Gestalt ('sysv', &versionSystem);
+ if (0x00000860 < (versionSystem & 0x0000FFFF)) {
+
+ GWorldPtr offscreen;
+ OSStatus err;
+ Rect bounds;
+
+ SetRect (&bounds, 0, 0, 320, 240);
+
+#if useDistantHdwrMem && useLocalHdwrMem
+ err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useDistantHdwrMem | noNewDevice);
+ if (err == noErr) {
+ dsp_vram_available = SDL_TRUE;
+ DisposeGWorld (offscreen);
+ }
+
+ err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useLocalHdwrMem | noNewDevice);
+ if (err == noErr) {
+ DisposeGWorld (offscreen);
+ dsp_agp_available = SDL_TRUE;
+ }
+#endif
+ }
+}
+
+static int DSp_GetMainDevice (_THIS, GDHandle *device)
+{
+
+#if TARGET_API_MAC_OSX
+ /* DSpUserSelectContext not available on OS X */
+ *device = GetMainDevice();
+ return 0;
+#else
+
+ DSpContextAttributes attrib;
+ DSpContextReference context;
+ DisplayIDType display_id;
+ GDHandle main_device;
+ GDHandle device_list;
+
+ device_list = GetDeviceList ();
+ main_device = GetMainDevice ();
+
+ /* Quick check to avoid slower method when only one display exists */
+ if ( (**device_list).gdNextGD == NULL ) {
+ *device = main_device;
+ return 0;
+ }
+
+ SDL_memset (&attrib, 0, sizeof (DSpContextAttributes));
+
+ /* These attributes are hopefully supported on all devices...*/
+ attrib.displayWidth = 640;
+ attrib.displayHeight = 480;
+ attrib.displayBestDepth = 8;
+ attrib.backBufferBestDepth = 8;
+ attrib.displayDepthMask = kDSpDepthMask_All;
+ attrib.backBufferDepthMask = kDSpDepthMask_All;
+ attrib.colorNeeds = kDSpColorNeeds_Require;
+ attrib.pageCount = 1;
+
+ if (noErr != DMGetDisplayIDByGDevice (main_device, &display_id, SDL_FALSE)) {
+ SDL_SetError ("Display Manager couldn't associate GDevice with a Display ID");
+ return (-1);
+ }
+
+ /* Put up dialog on main display to select which display to use */
+ if (noErr != DSpUserSelectContext (&attrib, display_id, NULL, &context)) {
+ SDL_SetError ("DrawSprocket couldn't create a context");
+ return (-1);
+ }
+
+ if (noErr != DSpContext_GetDisplayID (context, &display_id)) {
+ SDL_SetError ("DrawSprocket couldn't get display ID");
+ return (-1);
+ }
+
+ if (noErr != DMGetGDeviceByDisplayID (display_id, &main_device, SDL_FALSE)) {
+ SDL_SetError ("Display Manager couldn't associate Display ID with GDevice");
+ return (-1);
+ }
+
+ *device = main_device;
+ return (0);
+#endif
+}
+
+static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ NumVersion dsp_version = { 0x01, 0x00, 0x00, 0x00 };
+
+#if UNIVERSAL_INTERFACES_VERSION > 0x0320
+ dsp_version = DSpGetVersion ();
+#endif
+
+ if ( (dsp_version.majorRev == 1 && dsp_version.minorAndBugRev < 0x73) ||
+ (dsp_version.majorRev < 1) ) {
+
+ /* StandardAlert (kAlertStopAlert, "\pError!",
+ "\pI need DrawSprocket 1.7.3 or later!\n"
+ "You can find a newer version at http://www.apple.com/swupdates.",
+ NULL, NULL);
+ */
+ SDL_SetError ("DrawSprocket version is too old. Need 1.7.3 or later.");
+ return (-1);
+ }
+
+ if ( DSpStartup () != noErr ) {
+ SDL_SetError ("DrawSprocket couldn't startup");
+ return(-1);
+ }
+
+ /* Start DSpintosh events */
+ Mac_InitEvents(this);
+
+ /* Get a handle to the main monitor, or choose one on multiple monitor setups */
+ if ( DSp_GetMainDevice(this, &SDL_Display) < 0)
+ return (-1);
+
+ /* Determine pixel format */
+ vformat->BitsPerPixel = GetPixDepth ( (**SDL_Display).gdPMap );
+ dsp_old_depth = vformat->BitsPerPixel;
+
+ switch (vformat->BitsPerPixel) {
+ case 16:
+ vformat->Rmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Bmask = 0x0000001f;
+ break;
+ default:
+ break;
+ }
+
+ if ( DSp_CreatePalette (this) < 0 ) {
+ SDL_SetError ("Could not create palette");
+ return (-1);
+ }
+
+ /* Get a list of available fullscreen modes */
+ SDL_modelist = DSp_BuildModeList (SDL_Display,
+ &this->info.current_w, &this->info.current_h);
+ if (SDL_modelist == NULL) {
+ SDL_SetError ("DrawSprocket could not build a mode list");
+ return (-1);
+ }
+
+ /* Check for VRAM and AGP GWorlds for HW Blitting */
+ DSp_IsHWAvailable (this, vformat);
+
+ this->info.wm_available = 0;
+
+ if (dsp_vram_available || dsp_agp_available) {
+
+ this->info.hw_available = SDL_TRUE;
+
+ this->CheckHWBlit = DSp_CheckHWBlit;
+ this->info.blit_hw = SDL_TRUE;
+
+ this->FillHWRect = DSp_FillHWRect;
+ this->info.blit_fill = SDL_TRUE;
+
+ #ifdef DSP_TRY_CC_AND_AA
+ this->SetHWColorKey = DSp_SetHWColorKey;
+ this->info.blit_hw_CC = SDL_TRUE;
+
+ this->SetHWAlpha = DSp_SetHWAlpha;
+ this->info.blit_hw_A = SDL_TRUE;
+ #endif
+
+ }
+
+ return(0);
+}
+
+static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ static SDL_Rect *dsp_modes[16];
+ int i = 0, j = 0;
+
+ if ( format->BitsPerPixel == 0 )
+ return ( (SDL_Rect**) NULL );
+
+ while (SDL_modelist[i] != NULL) {
+
+ if (SDL_modelist[i]->x & format->BitsPerPixel) {
+ dsp_modes[j] = SDL_modelist[i];
+ j++;
+ }
+ i++;
+ }
+
+ dsp_modes[j] = NULL;
+
+ return dsp_modes;
+}
+
+/* Various screen update functions available */
+static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+#if ! TARGET_API_MAC_OSX
+
+static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */
+
+Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con )
+{
+ retrace_count++;
+
+ return 1; /* Darrell, is this right? */
+}
+
+static void DSp_SetHWError (OSStatus err, int is_agp)
+{
+ char message[1024];
+ const char *fmt, *mem;
+
+ if ( is_agp ) {
+ mem = "AGP Memory";
+ } else {
+ mem = "VRAM";
+ }
+ switch(err) {
+ case memFullErr:
+ fmt = "Hardware surface possible but not enough %s available";
+ break;
+ case cDepthErr:
+ fmt = "Hardware surface possible but invalid color depth";
+ break;
+ default:
+ fmt = "Hardware surface could not be allocated in %s - unknown error";
+ break;
+ }
+ SDL_snprintf(message, SDL_arraysize(message), fmt, mem);
+ SDL_SetError(message);
+}
+#endif // TARGET_API_MAC_OSX
+
+/* put up a dialog to verify display change */
+static int DSp_ConfirmSwitch () {
+
+ /* resource id's for dialog */
+ const int rDialog = 1002;
+ const int bCancel = 1;
+ const int bOK = 2;
+
+ DialogPtr dialog;
+ OSStatus err;
+ SInt32 response;
+ DialogItemIndex item = 0;
+ GrafPtr savePort;
+
+ GetPort (&savePort);
+
+ dialog = GetNewDialog (rDialog, NULL, (WindowPtr) -1);
+ if (dialog == NULL)
+ return (0);
+
+#if TARGET_API_MAC_CARBON
+ SetPort (GetDialogPort(dialog));
+#else
+ SetPort ((WindowPtr) dialog);
+#endif
+
+ SetDialogDefaultItem (dialog, bCancel);
+ SetDialogCancelItem (dialog, bCancel);
+
+ SetEventMask (everyEvent);
+ FlushEvents (everyEvent, 0);
+
+ /* On MacOS 8.5 or later, we can make the dialog go away after 15 seconds */
+ /* This is good since it's possible user can't even see the dialog! */
+ /* Requires linking to DialogsLib */
+ err = Gestalt(gestaltSystemVersion,&response);
+ if (err == noErr && response >= 0x00000850) {
+ SetDialogTimeout(dialog, bCancel, 15);
+ }
+
+ do {
+
+ ModalDialog ( NULL, &item );
+
+ } while ( item != bCancel && item != bOK && err != noErr);
+
+
+ DisposeDialog (dialog);
+ SetPort (savePort);
+
+ SetEventMask(everyEvent - autoKeyMask);
+ FlushEvents(everyEvent, 0);
+
+ return (item - 1);
+}
+
+static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current)
+{
+
+
+ if ( current->flags & SDL_OPENGL ) {
+ Mac_GL_Quit (this);
+ }
+
+ if (dsp_context != NULL) {
+
+ GWorldPtr front;
+ DSpContext_GetFrontBuffer (dsp_context, &front);
+
+ if (front != dsp_back_buffer)
+ DisposeGWorld (dsp_back_buffer);
+
+ if (current->hwdata)
+ SDL_free(current->hwdata);
+
+ DSpContext_SetState (dsp_context, kDSpContextState_Inactive );
+ DSpContext_Release (dsp_context);
+
+ dsp_context = NULL;
+ }
+
+ if (SDL_Window != NULL) {
+ DisposeWindow (SDL_Window);
+ SDL_Window = NULL;
+ }
+
+ current->pixels = NULL;
+ current->flags = 0;
+}
+
+static SDL_Surface *DSp_SetVideoMode(_THIS,
+ SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
+{
+
+#if !TARGET_API_MAC_OSX
+ DisplayIDType display_id;
+ Fixed freq;
+#endif
+ DSpContextAttributes attrib;
+ OSStatus err;
+ UInt32 rmask = 0, gmask = 0, bmask = 0;
+
+ int page_count;
+ int double_buf;
+ int hw_surface;
+ int use_dsp_back_buffer;
+
+ DSp_UnsetVideoMode (this, current);
+
+ if (bpp != dsp_old_depth)
+ DSp_DestroyPalette (this);
+
+ double_buf = (flags & SDL_DOUBLEBUF) != 0;
+ hw_surface = (flags & SDL_HWSURFACE) != 0;
+ use_dsp_back_buffer = !dsp_vram_available || !hw_surface ;
+
+ current->flags |= SDL_FULLSCREEN;
+
+rebuild:
+
+ if ( double_buf && use_dsp_back_buffer ) {
+ page_count = 2;
+ } else {
+ page_count = 1;
+ }
+
+ SDL_memset (&attrib, 0, sizeof (DSpContextAttributes));
+ attrib.displayWidth = width;
+ attrib.displayHeight = height;
+ attrib.displayBestDepth = bpp;
+ attrib.backBufferBestDepth = bpp;
+ attrib.displayDepthMask = kDSpDepthMask_All;
+ attrib.backBufferDepthMask = kDSpDepthMask_All;
+ attrib.colorNeeds = kDSpColorNeeds_Require;
+ attrib.colorTable = 0;
+ attrib.pageCount = page_count;
+ #if TARGET_API_MAC_OSX || UNIVERSAL_INTERFACES_VERSION == 0x0320
+
+ if ( DSpFindBestContext (&attrib, &dsp_context) != noErr ) {
+ SDL_SetError ("DrawSprocket couldn't find a context");
+ return NULL;
+ }
+
+ #else
+ if ( noErr != DMGetDisplayIDByGDevice (SDL_Display, &display_id, SDL_FALSE) ) {
+ SDL_SetError ("Display Manager couldn't associate GDevice with display_id");
+ return NULL;
+ }
+ if ( DSpFindBestContextOnDisplayID(&attrib, &dsp_context, display_id) != noErr ) {
+ SDL_SetError ("DrawSprocket couldn't find a suitable context on given display");
+ return NULL;
+ }
+
+ #endif
+ if ( DSpContext_Reserve (dsp_context, &attrib) != noErr ) {
+ SDL_SetError ("DrawSprocket couldn't get the needed resources to build the display");
+ return NULL;
+ }
+
+ if ( (err = DSpContext_SetState (dsp_context, kDSpContextState_Active)) != noErr ) {
+
+ if (err == kDSpConfirmSwitchWarning) {
+
+ if ( ! DSp_ConfirmSwitch () ) {
+
+ DSpContext_Release (dsp_context);
+ dsp_context = NULL;
+ SDL_SetError ("User cancelled display switch");
+ return NULL;
+ }
+ else
+ /* Have to reactivate context. Why? */
+ DSpContext_SetState (dsp_context, kDSpContextState_Active);
+
+ }
+ else {
+ SDL_SetError ("DrawSprocket couldn't activate the context");
+ return NULL;
+ }
+ }
+
+
+ if (bpp != dsp_old_depth) {
+
+ DSp_CreatePalette (this);
+
+ /* update format if display depth changed */
+ if (bpp == 16) {
+
+ rmask = 0x00007c00;
+ gmask = 0x000003e0;
+ bmask = 0x0000001f;
+ }
+ if ( ! SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, 0 ) ) {
+
+ SDL_SetError ("Could not reallocate video format.");
+ return(NULL);
+ }
+ }
+
+ if (!double_buf) {
+
+ /* single-buffer context */
+ DSpContext_GetFrontBuffer (dsp_context, &dsp_back_buffer);
+
+ current->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
+ if (current ->hwdata == NULL) {
+ SDL_OutOfMemory ();
+ return NULL;
+ }
+ current->hwdata->offscreen = dsp_back_buffer;
+ current->flags |= SDL_HWSURFACE;
+ this->UpdateRects = DSp_DirectUpdate;
+ }
+ else if ( use_dsp_back_buffer ) {
+
+ DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
+
+ current->flags |= SDL_DOUBLEBUF | SDL_SWSURFACE; /* only front buffer is in VRAM */
+ this->UpdateRects = DSp_DSpUpdate;
+ }
+ else if ( DSp_NewHWSurface(this, &dsp_back_buffer, bpp, width-1, height-1) == 0 ) {
+
+ current->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
+ if (current ->hwdata == NULL) {
+ SDL_OutOfMemory ();
+ return NULL;
+ }
+
+ SDL_memset (current->hwdata, 0, sizeof (private_hwdata));
+ current->hwdata->offscreen = dsp_back_buffer;
+ current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE;
+ this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */
+ }
+ else {
+
+ DSpContext_Release (dsp_context);
+ use_dsp_back_buffer = SDL_TRUE;
+ goto rebuild;
+ }
+
+ current->pitch = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF;
+ current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer));
+
+ current->w = width;
+ current->h = height;
+
+ #if ! TARGET_API_MAC_OSX
+
+ if (use_dsp_back_buffer) {
+
+ DSpContext_GetMonitorFrequency (dsp_context, &freq);
+ DSpContext_SetMaxFrameRate (dsp_context, freq >> 16);
+ }
+
+
+ if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) )
+ DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL);
+ #endif
+
+ if (bpp == 8)
+ current->flags |= SDL_HWPALETTE;
+
+ if (flags & SDL_OPENGL) {
+
+ Rect rect;
+ RGBColor rgb = { 0.0, 0.0, 0.0 };
+ GrafPtr save_port;
+
+ SetRect (&rect, 0, 0, width, height);
+ SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0);
+
+ if (SDL_Window == NULL) {
+
+ SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created.");
+ return NULL;
+ }
+
+ /* Set window color to black to avoid white flash*/
+ GetPort (&save_port);
+#if TARGET_API_MAC_CARBON
+ SetPort (GetWindowPort(SDL_Window));
+#else
+ SetPort (SDL_Window);
+#endif
+ RGBForeColor (&rgb);
+ PaintRect (&rect);
+ SetPort (save_port);
+
+ SetPortWindowPort (SDL_Window);
+ SelectWindow (SDL_Window);
+
+ if ( Mac_GL_Init (this) < 0 ) {
+
+ SDL_SetError ("DSp_SetVideoMode : could not create OpenGL context.");
+ return NULL;
+ }
+
+ current->flags |= SDL_OPENGL;
+ }
+
+ return current;
+}
+
+#ifdef DSP_TRY_CC_AND_AA
+
+static int DSp_MakeHWMask (_THIS, SDL_Surface *surface)
+{
+ GDHandle save_device;
+ CGrafPtr save_port;
+ GWorldPtr temp;
+ RGBColor black = { 0, 0, 0 };
+ RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
+ Rect rect;
+
+ Uint32 depth = GetPixDepth ( GetGDevPixMap (SDL_Display) );
+
+ SetRect (&rect, 0, 0, surface->w, surface->h);
+
+ if ( noErr != NewGWorld (&(surface->hwdata->mask), depth, &rect, 0, SDL_Display, 0 ) < 0 ) {
+
+ SDL_OutOfMemory ();
+ return (-1);
+ }
+
+ if ( noErr != NewGWorld (&temp, depth, &rect, 0 , SDL_Display, 0 ) ) {
+
+ SDL_OutOfMemory ();
+ return (-1);
+ }
+
+
+ GetGWorld (&save_port, &save_device);
+ SetGWorld (surface->hwdata->mask, SDL_Display);
+
+ RGBForeColor (&white);
+ PaintRect (&rect);
+
+ RGBBackColor (&(surface->hwdata->trans));
+
+ CopyBits ( GetPortBitMapForCopyBits(surface->hwdata->offscreen),
+ GetPortBitMapForCopyBits(surface->hwdata->mask),
+ &rect, &rect, transparent, NULL );
+
+ SetGWorld (surface->hwdata->mask, SDL_Display);
+ SetGWorld (save_port, save_device);
+ return (0);
+}
+
+static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha)
+{
+ surface->hwdata->alpha.red = (alpha / 255.0) * 65535;
+ surface->hwdata->alpha.blue = (alpha / 255.0) * 65535;
+ surface->hwdata->alpha.green = (alpha / 255.0) * 65535;
+
+ surface->flags |= SDL_SRCALPHA;
+
+ if (surface->flags & SDL_SRCCOLORKEY) {
+ return(DSp_MakeHWMask (this, surface));
+ }
+ return(0);
+}
+
+static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ CGrafPtr save_port;
+ GDHandle save_device;
+
+ GetGWorld (&save_port, &save_device);
+ SetGWorld (surface->hwdata->offscreen, NULL);
+
+ Index2Color (key, &(surface->hwdata->trans));
+ surface->flags |= SDL_SRCCOLORKEY;
+
+ SetGWorld (save_port, save_device);
+
+ if ( surface->flags & SDL_SRCALPHA ) {
+ return(DSp_MakeHWMask (this, surface));
+ }
+ return(0);
+}
+
+#endif /* DSP_TRY_CC_AND_AA */
+
+static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height) {
+
+ OSStatus err;
+ Rect bounds;
+
+ SetRect (&bounds, 0, 0, width, height);
+
+ #if useDistantHdwrMem && useLocalHdwrMem
+ if (dsp_vram_available) {
+ /* try VRAM */
+ err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useDistantHdwrMem | noNewDevice );
+ if (err != noErr)
+ DSp_SetHWError (err, SDL_FALSE);
+ else
+ return (0);
+ }
+
+ if (dsp_agp_available) {
+ /* try AGP */
+ err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useLocalHdwrMem | noNewDevice );
+
+ if (err != noErr)
+ DSp_SetHWError (err, SDL_TRUE);
+ else
+ return (0);
+ }
+#endif
+
+ return (-1);
+}
+
+static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ GWorldPtr temp;
+
+ if ( DSp_NewHWSurface (this, &temp, surface->format->BitsPerPixel, surface->w, surface->h) < 0 )
+ return (-1);
+
+ surface->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
+ if (surface->hwdata == NULL) {
+ SDL_OutOfMemory ();
+ return -1;
+ }
+
+ SDL_memset (surface->hwdata, 0, sizeof(private_hwdata));
+ surface->hwdata->offscreen = temp;
+ surface->pitch = GetPixRowBytes (GetPortPixMap (temp)) & 0x3FFF;
+ surface->pixels = GetPixBaseAddr (GetPortPixMap (temp));
+ surface->flags |= SDL_HWSURFACE;
+#ifdef DSP_TRY_CC_AND_AA
+ surface->flags |= SDL_HWACCEL;
+#endif
+ return 0;
+}
+
+static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (surface->hwdata->offscreen != NULL)
+ DisposeGWorld (surface->hwdata->offscreen);
+ SDL_free(surface->hwdata);
+
+ surface->pixels = NULL;
+}
+
+static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest)
+{
+ int accelerated;
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( ! this->info.blit_hw_A ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( ! this->info.blit_hw_CC ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+ src->map->hw_blit = DSp_HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ CGrafPtr save_port;
+ GDHandle save_device;
+ Rect src_rect, dst_rect;
+ RGBColor black = { 0, 0, 0 };
+ RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
+
+#ifdef DSP_TRY_CC_AND_AA
+ UInt32 mode;
+#endif
+
+ SetRect (&src_rect, srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h);
+ SetRect (&dst_rect, dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h);
+
+ GetGWorld (&save_port, &save_device);
+ SetGWorld (dst->hwdata->offscreen, NULL);
+
+ RGBForeColor (&black);
+ RGBBackColor (&white);
+
+#ifdef DSP_TRY_CC_AND_AA
+
+ if ( (src->flags & SDL_SRCCOLORKEY) &&
+ (src->flags & SDL_SRCALPHA) ) {
+
+ OpColor (&(src->hwdata->alpha));
+
+ CopyDeepMask ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
+ GetPortBitMapForCopyBits(src->hwdata->mask),
+ GetPortBitMapForCopyBits(dst->hwdata->offscreen),
+ &src_rect, &src_rect, &dst_rect,
+ blend,
+ NULL );
+ }
+ else {
+
+ if ( src->flags & SDL_SRCCOLORKEY) {
+ RGBBackColor (&(src->hwdata->trans) );
+ mode = transparent;
+ }
+ else if (src->flags & SDL_SRCALPHA) {
+
+ OpColor (&(src->hwdata->alpha));
+ mode = blend;
+ }
+ else {
+
+ mode = srcCopy;
+ }
+
+ CopyBits ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
+ GetPortBitMapForCopyBits(dst->hwdata->offscreen),
+ &src_rect, &dst_rect, mode, NULL );
+ }
+#else
+
+ CopyBits ( &(((GrafPtr)(src->hwdata->offscreen))->portBits),
+ &(((GrafPtr)(dst->hwdata->offscreen))->portBits),
+ &src_rect, &dst_rect, srcCopy, NULL );
+
+#endif /* DSP_TRY_CC_AND_AA */
+
+ SetGWorld (save_port, save_device);
+
+ return(0);
+}
+
+static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
+{
+ CGrafPtr save_port;
+ GDHandle save_device;
+ Rect fill_rect;
+ RGBColor rgb;
+
+ SetRect (&fill_rect, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
+
+ GetGWorld (&save_port, &save_device);
+ SetGWorld (dst->hwdata->offscreen, NULL);
+
+ Index2Color (color, &rgb);
+
+ RGBForeColor (&rgb);
+ PaintRect (&fill_rect);
+
+ SetGWorld (save_port, save_device);
+
+ return(0);
+}
+
+static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( (surface->flags & SDL_HWSURFACE) ) {
+ CGrafPtr dsp_front_buffer, save_port;
+ Rect rect;
+
+ #if ! TARGET_API_MAC_OSX
+ unsigned int old_count;
+ #endif
+
+ /* pseudo page flipping for VRAM back buffer*/
+ DSpContext_GetFrontBuffer (dsp_context, &dsp_front_buffer);
+ SetRect (&rect, 0, 0, surface->w-1, surface->h-1);
+
+ GetPort ((GrafPtr *)&save_port);
+ SetPort ((GrafPtr)dsp_front_buffer);
+
+ /* wait for retrace */
+ /* I have tried doing the swap in interrupt routine (VBL Proc) to do */
+ /* it asynchronously, but apparently CopyBits isn't interrupt safe */
+
+ #if ! TARGET_API_MAC_OSX
+ #ifndef DSP_NO_SYNC_VBL
+ old_count = retrace_count;
+ while (old_count == retrace_count)
+ ;
+ #endif
+ #endif
+
+ CopyBits ( GetPortBitMapForCopyBits(dsp_back_buffer),
+ GetPortBitMapForCopyBits(dsp_front_buffer),
+ &rect, &rect, srcCopy, NULL );
+
+ SetPort ((GrafPtr)save_port);
+
+ } else {
+ /* not really page flipping at all: DSp just blits the dirty rectangles from DSp_UpdateRects */
+ Boolean busy_flag;
+ DSpContext_SwapBuffers (dsp_context, NULL, &busy_flag); /* this waits for VBL */
+ DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
+ surface->pixels = GetPixBaseAddr( GetPortPixMap(dsp_back_buffer) );
+ }
+ return(0);
+}
+
+static int DSp_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( LockPixels (GetGWorldPixMap (surface->hwdata->offscreen)) )
+ return 0;
+ else
+ return -1;
+}
+
+static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ UnlockPixels (GetGWorldPixMap (surface->hwdata->offscreen));
+}
+
+static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
+{
+ return;
+}
+
+static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
+{
+#if ! TARGET_API_MAC_OSX /* Unsupported DSp in here */
+ int i;
+ Rect rect;
+
+ for (i = 0; i < numrects; i++) {
+
+ rect.top = sdl_rects[i].y;
+ rect.left = sdl_rects[i].x;
+ rect.bottom = sdl_rects[i].h + sdl_rects[i].y;
+ rect.right = sdl_rects[i].w + sdl_rects[i].x;
+
+ DSpContext_InvalBackBufferRect (dsp_context, &rect);
+ }
+#endif
+}
+
+static int DSp_CreatePalette(_THIS) {
+
+
+ /* Create our palette */
+ SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
+ if ( SDL_CTab == nil ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ (**SDL_CTab).ctSeed = GetCTSeed();
+ (**SDL_CTab).ctFlags = 0;
+ (**SDL_CTab).ctSize = 255;
+ CTabChanged(SDL_CTab);
+ SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
+
+ return 0;
+}
+
+static int DSp_DestroyPalette(_THIS) {
+
+ /* Free palette and restore original one */
+ if ( SDL_CTab != nil ) {
+ DisposeHandle((Handle)SDL_CTab);
+ SDL_CTab = nil;
+ }
+ if ( SDL_CPal != nil ) {
+ DisposePalette(SDL_CPal);
+ SDL_CPal = nil;
+ }
+ RestoreDeviceClut(SDL_Display);
+
+ return (0);
+}
+
+static int DSp_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ CTabHandle cTab;
+
+ int i;
+
+ cTab = SDL_CTab;
+
+ /* Verify the range of colors */
+ if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) {
+ return(0);
+ }
+
+ /* Set the screen palette and update the display */
+ for(i = 0; i < ncolors; i++) {
+ int j = firstcolor + i;
+ (**cTab).ctTable[j].value = j;
+ (**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r;
+ (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g;
+ (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b;
+ }
+
+ SetGDevice(SDL_Display);
+ SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable);
+
+ return(1);
+}
+
+void DSp_VideoQuit(_THIS)
+{
+ int i;
+
+ /* Free current video mode */
+ DSp_UnsetVideoMode(this, this->screen);
+
+ /* Free Palette and restore original */
+ DSp_DestroyPalette (this);
+
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+ Mac_QuitGamma(this);
+#endif
+
+ /* Free list of video modes */
+ if ( SDL_modelist != NULL ) {
+ for ( i=0; SDL_modelist[i]; i++ ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ SDL_modelist = NULL;
+ }
+
+ /* Unload DrawSprocket */
+ DSpShutdown ();
+}
+
+#if SDL_VIDEO_OPENGL
+
+/* swap buffers with v-sync */
+static void DSp_GL_SwapBuffers (_THIS) {
+
+ #ifndef DSP_NO_SYNC_OPENGL
+
+ unsigned int old_count;
+
+ old_count = retrace_count;
+ while (old_count == retrace_count)
+ ;
+ #endif
+
+ aglSwapBuffers (glContext);
+}
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.h b/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.h
new file mode 100644
index 0000000..7fc0896
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/macdsp/SDL_dspvideo.h
@@ -0,0 +1,54 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_dspvideo_h
+#define _SDL_dspvideo_h
+
+#if TARGET_API_MAC_OSX
+# include <DrawSprocket/DrawSprocket.h> /* Drawsprocket.framework */
+#else
+#include <DrawSprocket.h>
+#endif
+
+#include "../maccommon/SDL_lowvideo.h"
+
+/* DrawSprocket specific information */
+struct DSpInfo {
+ DSpContextReference dsp_context;
+ CGrafPtr dsp_back_buffer;
+ int dsp_old_depth;
+
+ /* Flags for hw acceleration */
+ int dsp_vram_available;
+ int dsp_agp_available;
+
+
+};
+/* Old variable names */
+#define dsp_context (this->hidden->dspinfo->dsp_context)
+#define dsp_back_buffer (this->hidden->dspinfo->dsp_back_buffer)
+#define dsp_old_depth (this->hidden->dspinfo->dsp_old_depth)
+#define dsp_vram_available (this->hidden->dspinfo->dsp_vram_available)
+#define dsp_agp_available (this->hidden->dspinfo->dsp_agp_available)
+
+#endif /* _SDL_dspvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.c b/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.c
new file mode 100644
index 0000000..4c48881
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.c
@@ -0,0 +1,745 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#if USE_QUICKTIME
+#include <QuickTime/Movies.h>
+#endif
+#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+#include <Carbon.h>
+/* The fullscreen code requires the QuickTime framework, and the window
+ is still at the back on Mac OS X, which is where this code is needed.
+ */
+#if USE_QUICKTIME
+#include <Movies.h>
+#endif
+#else
+#include <Quickdraw.h>
+#include <LowMem.h>
+#include <Gestalt.h>
+#include <Devices.h>
+#include <DiskInit.h>
+#include <QDOffscreen.h>
+#endif
+
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_romvideo.h"
+#include "../maccommon/SDL_macgl_c.h"
+#include "../maccommon/SDL_macwm_c.h"
+#include "../maccommon/SDL_macmouse_c.h"
+#include "../maccommon/SDL_macevents_c.h"
+
+/* Initialization/Query functions */
+static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int ROM_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void ROM_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int ROM_LockHWSurface(_THIS, SDL_Surface *surface);
+static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
+/* Saved state for the menu bar */
+static RgnHandle gSaveGrayRgn = nil;
+static short gSaveMenuBar = 0;
+static Boolean gSaveCSVis = true;
+
+#if powerc
+/* Mixed mode glue to activate the 68K emulator and twiddle a register */
+#define ONEWORDSTUB(p1) \
+ { 0x41FA, 0x0010, 0x209F, (p1), 0x41FA, \
+ 0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
+
+#define TWOWORDSTUB(p1,p2) \
+ { 0x41FA, 0x0012, 0x209F, (p1), (p2), 0x41FA, \
+ 0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
+
+#define THREEWORDSTUB(p1,p2,p3) \
+ { 0x41FA, 0x0014, 0x209F, (p1), (p2), (p3), 0x41FA, \
+ 0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
+
+/* ControlStrip inline glue for PowerPC */
+static pascal Boolean SBIsControlStripVisible(void)
+{
+ static short procData[] = TWOWORDSTUB(0x7000, 0xAAF2);
+ ProcInfoType procInfo = kD0DispatchedPascalStackBased
+ | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
+ | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode);
+
+ return((Boolean) CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x00));
+}
+
+static pascal void SBShowHideControlStrip(Boolean showIt)
+{
+ static short procData[] = THREEWORDSTUB(0x303C, 0x0101, 0xAAF2);
+ ProcInfoType procInfo = kD0DispatchedPascalStackBased
+ | DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
+ | DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean)));
+
+ CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x01, showIt);
+}
+#endif /* powerc */
+#endif /* !TARGET_API_MAC_CARBON */
+
+/* Macintosh toolbox driver bootstrap functions */
+
+static int ROM_Available(void)
+{
+ return(1);
+}
+
+static void ROM_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *ROM_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = ROM_VideoInit;
+ device->ListModes = ROM_ListModes;
+ device->SetVideoMode = ROM_SetVideoMode;
+ device->SetColors = ROM_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = ROM_VideoQuit;
+ device->AllocHWSurface = ROM_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = ROM_LockHWSurface;
+ device->UnlockHWSurface = ROM_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = ROM_FreeHWSurface;
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+ device->SetGammaRamp = Mac_SetGammaRamp;
+ device->GetGammaRamp = Mac_GetGammaRamp;
+#endif
+#if SDL_VIDEO_OPENGL
+ device->GL_MakeCurrent = Mac_GL_MakeCurrent;
+ device->GL_SwapBuffers = Mac_GL_SwapBuffers;
+ device->GL_LoadLibrary = Mac_GL_LoadLibrary;
+ device->GL_GetProcAddress = Mac_GL_GetProcAddress;
+#endif /* Have OpenGL */
+ device->SetCaption = Mac_SetCaption;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = Mac_FreeWMCursor;
+ device->CreateWMCursor = Mac_CreateWMCursor;
+ device->ShowWMCursor = Mac_ShowWMCursor;
+ device->WarpWMCursor = Mac_WarpWMCursor;
+ device->InitOSKeymap = Mac_InitOSKeymap;
+ device->PumpEvents = Mac_PumpEvents;
+
+ device->free = ROM_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap TOOLBOX_bootstrap = {
+ "toolbox", "MacOS ROM Toolbox",
+ ROM_Available, ROM_CreateDevice
+};
+
+
+static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ long info;
+
+ /* Check out some things about the system */
+ Gestalt(gestaltQuickdrawVersion, &info);
+ if ( info == gestaltOriginalQD ) {
+ SDL_SetError("Color Quickdraw not available");
+ return(-1);
+ }
+
+ /* Start ROMintosh events */
+ Mac_InitEvents(this);
+
+ /* Get a handle to the main monitor */
+ SDL_Display = GetMainDevice();
+
+ /* Determine the current screen size */
+ this->info.current_w = (**SDL_Display).gdRect.right;
+ this->info.current_h = (**SDL_Display).gdRect.bottom;
+
+ /* Determine pixel format */
+ vformat->BitsPerPixel = (**(**SDL_Display).gdPMap).pixelSize;
+ switch (vformat->BitsPerPixel) {
+ case 16: /* 5-5-5 RGB */
+ vformat->Rmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Bmask = 0x0000001f;
+ break;
+ default:
+ break;
+ }
+
+ /* Create our palette */
+ SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
+ if ( SDL_CTab == nil ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ (**SDL_CTab).ctSeed = GetCTSeed();
+ (**SDL_CTab).ctFlags = 0;
+ (**SDL_CTab).ctSize = 255;
+ CTabChanged(SDL_CTab);
+ SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
+
+ /* Get a list of available fullscreen modes */
+ SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist ) {
+ SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[0] ) {
+ SDL_modelist[0]->x = 0;
+ SDL_modelist[0]->y = 0;
+ SDL_modelist[0]->w = (**SDL_Display).gdRect.right;
+ SDL_modelist[0]->h = (**SDL_Display).gdRect.bottom;
+ }
+ SDL_modelist[1] = NULL;
+ }
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if ( this->screen->format->BitsPerPixel == format->BitsPerPixel ) {
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ return(SDL_modelist);
+ } else {
+ return((SDL_Rect **)-1);
+ }
+ } else {
+ return((SDL_Rect **)0);
+ }
+}
+
+static void ROM_HideMenuBar(_THIS)
+{
+#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
+ RgnHandle drawRgn = nil;
+ RgnHandle tempRgn = nil;
+ RgnHandle grayRgn = nil;
+ WindowPtr window = nil;
+ GDHandle gd = nil;
+ GrafPtr savePort;
+ long response;
+ short height;
+ EventRecord theEvent;
+
+ height = GetMBarHeight();
+
+ if ( height > 0 ) {
+ tempRgn = NewRgn();
+ drawRgn = NewRgn();
+ gSaveGrayRgn = NewRgn();
+ if ( ! tempRgn || ! drawRgn || ! gSaveGrayRgn ) {
+ goto CLEANUP;
+ }
+ grayRgn = GetGrayRgn(); /* No need to check for this */
+
+ GetPort(&savePort);
+
+ /* Hide the control strip if it's present, and record its
+ previous position into the dirty region for redrawing.
+ This isn't necessary, but may help catch stray bits. */
+ CopyRgn(grayRgn, tempRgn);
+ if (!Gestalt(gestaltControlStripAttr, &response) &&
+ (response & (1L << gestaltControlStripExists))) {
+ gSaveCSVis = SBIsControlStripVisible();
+ if (gSaveCSVis)
+ SBShowHideControlStrip(false);
+ }
+ DiffRgn(grayRgn, tempRgn, drawRgn);
+
+ /* Save the gray region once the control strip is hidden*/
+ CopyRgn(grayRgn, gSaveGrayRgn);
+
+ /* Change the menu height in lowmem */
+ gSaveMenuBar = height;
+ LMSetMBarHeight(0);
+
+ /* Walk the monitor rectangles, and combine any pieces that
+ aren't in GrayRgn: menubar, round corners, fake floaters. */
+ for(gd = GetDeviceList(); gd; gd = GetNextDevice(gd))
+ {
+ if (!TestDeviceAttribute(gd, screenDevice)) continue;
+ if (!TestDeviceAttribute(gd, screenActive)) continue;
+
+ RectRgn(tempRgn, &(*gd)->gdRect); /* Get the whole screen */
+ DiffRgn(tempRgn, grayRgn, tempRgn); /* Subtract out GrayRgn */
+ UnionRgn(tempRgn, drawRgn, drawRgn);/* Combine all the bits */
+ }
+
+ /* Add the bits into the GrayRgn */
+ UnionRgn(drawRgn, grayRgn, grayRgn);
+
+ /* Modify the vis regions of exposed windows */
+ window = (FrontWindow()) ? FrontWindow() : (WindowPtr) -1L;
+ PaintBehind(window, drawRgn);
+ CalcVisBehind(window, drawRgn);
+
+ SetPort(savePort);
+
+ /* Yield time so that floaters can catch up */
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ }
+
+CLEANUP:
+
+ if (tempRgn) DisposeRgn(tempRgn);
+ if (drawRgn) DisposeRgn(drawRgn);
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+static void ROM_ShowMenuBar(_THIS)
+{
+#if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
+ RgnHandle drawRgn = nil;
+ RgnHandle menuRgn = nil;
+ RgnHandle tempRgn = nil;
+ RgnHandle grayRgn = nil;
+ WindowPtr window = nil;
+ GrafPtr wMgrPort;
+ GrafPtr savePort;
+ Rect menuRect;
+ long response;
+ short height;
+ EventRecord theEvent;
+ RGBColor saveRGB;
+ RGBColor blackRGB = { 0, 0, 0 };
+
+ height = GetMBarHeight();
+
+ if ((height <= 0) && (gSaveMenuBar > 0)) {
+ drawRgn = NewRgn();
+ menuRgn = NewRgn();
+ tempRgn = NewRgn();
+ if ( ! tempRgn || ! drawRgn || ! gSaveGrayRgn ) {
+ goto CLEANUP;
+ }
+ grayRgn = GetGrayRgn(); /* No need to check for this */
+
+ GetPort(&savePort);
+ GetWMgrPort(&wMgrPort);
+
+ /* Set the height properly */
+ LMSetMBarHeight(gSaveMenuBar);
+
+ /* Restore the old GrayRgn: rounded corners, etc, but not
+ the menubar -- subtract that out first! */
+ if (gSaveGrayRgn)
+ {
+ menuRect = (*GetMainDevice())->gdRect;
+ menuRect.bottom = menuRect.top + gSaveMenuBar;
+ RectRgn(menuRgn, &menuRect);
+
+ DiffRgn(grayRgn, gSaveGrayRgn, drawRgn); /* What do we inval? */
+ DiffRgn(drawRgn, menuRgn, drawRgn); /* Clip out the menu */
+
+ /* Now redraw the corners and other bits black */
+ SetPort(wMgrPort);
+ GetClip(tempRgn);
+ SetClip(drawRgn);
+ GetForeColor(&saveRGB);
+ RGBForeColor(&blackRGB);
+ PaintRgn(drawRgn);
+ RGBForeColor(&saveRGB);
+ SetClip(tempRgn);
+ SetPort(savePort);
+
+ UnionRgn(drawRgn, menuRgn, drawRgn); /* Put back the menu */
+
+ /* Now actually restore the GrayRgn */
+ CopyRgn(gSaveGrayRgn, grayRgn);
+ DisposeRgn(gSaveGrayRgn);
+ gSaveGrayRgn = nil;
+ }
+
+ /* Modify the vis regions of exposed windows and draw menubar */
+ window = (FrontWindow()) ? FrontWindow() : (WindowPtr) -1L;
+ PaintBehind(window, drawRgn);
+ CalcVisBehind(window, drawRgn);
+ DrawMenuBar();
+
+ SetPort(savePort);
+ gSaveMenuBar = 0;
+
+ /* Now show the control strip if it's present */
+ if (!Gestalt(gestaltControlStripAttr, &response) &&
+ (response & (1L << gestaltControlStripExists)))
+ {
+ if (gSaveCSVis && !SBIsControlStripVisible())
+ SBShowHideControlStrip(true);
+ gSaveCSVis = true;
+ }
+
+ /* Yield time so that floaters can catch up */
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ EventAvail(0, &theEvent);
+ }
+
+CLEANUP:
+
+ if (drawRgn) DisposeRgn(drawRgn);
+ if (menuRgn) DisposeRgn(menuRgn);
+ if (tempRgn) DisposeRgn(tempRgn);
+#endif /* !TARGET_API_MAC_CARBON */
+}
+
+/* Various screen update functions available */
+static void ROM_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void ROM_WindowUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+static void ROM_UnsetVideoMode(_THIS, SDL_Surface *current)
+{
+ /* Free the current window, if any */
+ if ( SDL_Window != nil ) {
+ GWorldPtr memworld;
+
+ /* Handle OpenGL support */
+ Mac_GL_Quit(this);
+
+ memworld = (GWorldPtr)GetWRefCon(SDL_Window);
+ if ( memworld != nil ) {
+ UnlockPixels(GetGWorldPixMap(memworld));
+ DisposeGWorld(memworld);
+ }
+ if ( (current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+#if USE_QUICKTIME
+ EndFullScreen(fullscreen_ctx, nil);
+ SDL_Window = nil;
+#else
+ ROM_ShowMenuBar(this);
+#endif
+ }
+ }
+ current->pixels = NULL;
+ current->flags &= ~(SDL_HWSURFACE|SDL_FULLSCREEN);
+}
+
+static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Rect wrect, orect;
+#if TARGET_API_MAC_CARBON
+ Rect tmprect;
+#endif
+
+ /* Free any previous video mode */
+ ROM_UnsetVideoMode(this, current);
+
+ /* Create the ROM window and SDL video surface */
+ current->flags = 0; /* Clear flags */
+ current->w = width;
+ current->h = height;
+ SetRect(&wrect, 0, 0, width, height);
+ if ( SDL_Window ) {
+ /* If we recreate the window, don't move it around */
+#if TARGET_API_MAC_CARBON
+ orect = *GetWindowPortBounds(SDL_Window, &tmprect);
+#else
+ orect = SDL_Window->portRect;
+#endif
+ OffsetRect(&wrect, orect.left, orect.top);
+ } else {
+ /* Center the window the first time we show it */
+ OffsetRect(&wrect,
+ (SDL_modelist[0]->w-width)/2, (SDL_modelist[0]->h-height)/2);
+ }
+
+#if defined(__MACOSX__) && !USE_QUICKTIME
+ /* Hum.. fullscreen mode is broken */
+ flags &= ~SDL_FULLSCREEN;
+#endif
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ /* Create the fullscreen window and use screen bits */
+ current->flags |= SDL_HWSURFACE|SDL_FULLSCREEN;
+ if ( SDL_Window ) {
+ DisposeWindow(SDL_Window);
+ }
+#if USE_QUICKTIME
+ BeginFullScreen(&fullscreen_ctx, nil, 0,0, &SDL_Window, nil, 0);
+#else
+ SDL_Window = NewCWindow(nil, &wrect, "\p", true, plainDBox,
+ (WindowPtr)-1, false, 0);
+ ROM_HideMenuBar(this);
+#endif
+ current->pitch = (**(**SDL_Display).gdPMap).rowBytes & 0x3FFF;
+ current->pixels = (**(**SDL_Display).gdPMap).baseAddr;
+ this->UpdateRects = ROM_DirectUpdate;
+ } else {
+ GWorldPtr memworld;
+ PixMapHandle pixmap;
+ int style;
+
+ style = noGrowDocProc;
+ if ( flags & SDL_NOFRAME ) {
+ style = plainDBox;
+ current->flags |= SDL_NOFRAME;
+ } else
+ if ( flags & SDL_RESIZABLE ) {
+ style = zoomDocProc;
+ current->flags |= SDL_RESIZABLE;
+ }
+ if ( SDL_Window && (style == current_style) ) {
+ /* Resize existing window, if necessary */
+ if ( ((orect.right-orect.left) != width) ||
+ ((orect.bottom-orect.top) != height) ) {
+ SizeWindow(SDL_Window, width, height, false);
+ }
+ } else {
+ /* Recreate the window in the new style */
+ if ( SDL_Window ) {
+ DisposeWindow(SDL_Window);
+ }
+ SDL_Window = NewCWindow(nil, &wrect, "\p", true,
+ style, (WindowPtr)-1, true, 0);
+
+ /* Set the window title, if any */
+ { char *title;
+ SDL_WM_GetCaption(&title, NULL);
+ if ( title ) {
+ Mac_SetCaption(this, title, NULL);
+ }
+ }
+ }
+ current_style = style;
+ SetPalette(SDL_Window, SDL_CPal, false);
+ ActivatePalette(SDL_Window);
+ if ( NewGWorld(&memworld, 0,
+#if TARGET_API_MAC_CARBON
+ GetWindowPortBounds(SDL_Window, &tmprect),
+#else
+ &SDL_Window->portRect,
+#endif
+ SDL_CTab, nil, 0) != noErr ) {
+ SDL_SetError("NewGWorld() failed");
+ return(NULL);
+ }
+ SetWRefCon(SDL_Window, (long)memworld);
+ pixmap = GetGWorldPixMap(memworld);
+ LockPixels(pixmap);
+ current->pitch = (**pixmap).rowBytes & 0x3FFF;
+ current->pixels = GetPixBaseAddr(pixmap);
+ this->UpdateRects = ROM_WindowUpdate;
+ }
+ SetPortWindowPort(SDL_Window);
+ SelectWindow(SDL_Window);
+
+ /* Handle OpenGL support */
+ if ( flags & SDL_OPENGL ) {
+ if ( Mac_GL_Init(this) == 0 ) {
+ current->flags |= SDL_OPENGL;
+ } else {
+ current = NULL;
+ }
+ }
+
+ if ( (flags & SDL_HWPALETTE) && (flags & SDL_FULLSCREEN) )
+ current->flags |= SDL_HWPALETTE;
+
+ /* We're live! */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+static int ROM_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void ROM_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ /* The application is already updating the visible video memory */
+ return;
+}
+
+static void ROM_WindowUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ GWorldPtr memworld;
+ GrafPtr saveport;
+ CGrafPtr thePort;
+ const BitMap *memBits;
+ const BitMap *winBits;
+ int i;
+ Rect update;
+
+ /* Copy from the offscreen GWorld to the window port */
+ GetPort(&saveport);
+ SetPortWindowPort(SDL_Window);
+ thePort = GetWindowPort(SDL_Window);
+ memworld = (GWorldPtr)GetWRefCon(SDL_Window);
+#if TARGET_API_MAC_CARBON && ACCESSOR_CALLS_ARE_FUNCTIONS
+ memBits = GetPortBitMapForCopyBits((CGrafPtr) memworld);
+#else
+ memBits = &((GrafPtr)memworld)->portBits;
+#endif
+#if TARGET_API_MAC_CARBON && ACCESSOR_CALLS_ARE_FUNCTIONS
+ winBits = GetPortBitMapForCopyBits(thePort);
+#else
+ winBits = &SDL_Window->portBits;
+#endif
+ for ( i=0; i<numrects; ++i ) {
+ update.left = rects[i].x;
+ update.right = rects[i].x+rects[i].w;
+ update.top = rects[i].y;
+ update.bottom = rects[i].y+rects[i].h;
+ CopyBits(memBits, winBits,
+ &update, &update, srcCopy, nil);
+ }
+#if TARGET_API_MAC_CARBON
+ if ( QDIsPortBuffered(thePort) ) {
+ QDFlushPortBuffer(thePort, NULL);
+ }
+#endif
+ SetPort(saveport);
+}
+
+static int ROM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ CTabHandle cTab;
+ int i;
+
+ /* Get the colortable from the either the display or window */
+ if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ cTab = (**(**SDL_Display).gdPMap).pmTable;
+ } else {
+ cTab = SDL_CTab;
+ }
+
+ /* Verify the range of colors */
+ if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) {
+ return(0);
+ }
+
+ /* Set the screen palette and update the display */
+ for ( i=0; i< ncolors; ++i ) {
+ int j = firstcolor + i;
+ (**cTab).ctTable[j].value = j;
+ (**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r;
+ (**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g;
+ (**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b;
+ }
+
+#if 0
+ if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN )
+#endif
+ {
+ GDevice **odisplay;
+ odisplay = GetGDevice();
+ SetGDevice(SDL_Display);
+ SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable);
+ SetGDevice(odisplay);
+ }
+ return(1);
+}
+
+void ROM_VideoQuit(_THIS)
+{
+ int i;
+
+ /* Free current video mode */
+ ROM_UnsetVideoMode(this, this->screen);
+ if ( SDL_Window ) {
+ DisposeWindow(SDL_Window);
+ SDL_Window = nil;
+ }
+
+ /* Free palette and restore original one */
+ if ( SDL_CTab != nil ) {
+ DisposeHandle((Handle)SDL_CTab);
+ SDL_CTab = nil;
+ }
+ if ( SDL_CPal != nil ) {
+ DisposePalette(SDL_CPal);
+ SDL_CPal = nil;
+ }
+ RestoreDeviceClut(GetMainDevice());
+
+#if SDL_MACCLASSIC_GAMMA_SUPPORT
+ Mac_QuitGamma(this);
+#endif
+
+ /* Free list of video modes */
+ if ( SDL_modelist != NULL ) {
+ for ( i=0; SDL_modelist[i]; ++i ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ SDL_modelist = NULL;
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.h b/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.h
new file mode 100644
index 0000000..0380f91
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/macrom/SDL_romvideo.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_romvideo_h
+#define _SDL_romvideo_h
+
+#include "../maccommon/SDL_lowvideo.h"
+
+#endif /* _SDL_romvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/math_private.h b/distrib/sdl-1.2.15/src/video/math_private.h
new file mode 100644
index 0000000..1087d7d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/math_private.h
@@ -0,0 +1,173 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $Id$
+ */
+
+#ifndef _MATH_PRIVATE_H_
+#define _MATH_PRIVATE_H_
+
+#include "SDL_name.h"
+#include "SDL_endian.h"
+
+#define huge really_big /* huge is a reserved keyword in VC++ 6.0 */
+#define u_int32_t uint32_t
+
+/* The original fdlibm code used statements like:
+ n0 = ((*(int*)&one)>>29)^1; * index of high word *
+ ix0 = *(n0+(int*)&x); * high word of x *
+ ix1 = *((1-n0)+(int*)&x); * low word of x *
+ to dig two 32 bit words out of the 64 bit IEEE floating point
+ value. That is non-ANSI, and, moreover, the gcc instruction
+ scheduler gets it wrong. We instead use the following macros.
+ Unlike the original code, we determine the endianness at compile
+ time, not at run time; I don't see much benefit to selecting
+ endianness at run time. */
+
+/* A union which permits us to convert between a double and two 32 bit
+ ints. */
+
+/*
+ * Math on arm is special:
+ * For FPA, float words are always big-endian.
+ * For VFP, floats words follow the memory system mode.
+ */
+
+#if (SDL_BYTEORDER == SDL_BIG_ENDIAN) || \
+ (!defined(__VFP_FP__) && (defined(__arm__) || defined(__thumb__)))
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t msw;
+ u_int32_t lsw;
+ } parts;
+} ieee_double_shape_type;
+
+#else
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+/* Get two 32 bit ints from a double. */
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ ieee_double_shape_type gl_u; \
+ gl_u.value = (d); \
+ (i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ ieee_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+ int. */
+
+typedef union
+{
+ float value;
+ u_int32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+
+#define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+
+/* Set a float from a 32 bit int. */
+
+#define SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+#endif /* _MATH_PRIVATE_H_ */
diff --git a/distrib/sdl-1.2.15/src/video/mmx.h b/distrib/sdl-1.2.15/src/video/mmx.h
new file mode 100644
index 0000000..dcee7b0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/mmx.h
@@ -0,0 +1,704 @@
+/* mmx.h
+
+ MultiMedia eXtensions GCC interface library for IA32.
+
+ To use this library, simply include this header file
+ and compile with GCC. You MUST have inlining enabled
+ in order for mmx_ok() to work; this can be done by
+ simply using -O on the GCC command line.
+
+ Compiling with -DMMX_TRACE will cause detailed trace
+ output to be sent to stderr for each mmx operation.
+ This adds lots of code, and obviously slows execution to
+ a crawl, but can be very useful for debugging.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ 1997-99 by H. Dietz and R. Fisher
+
+ Notes:
+ It appears that the latest gas has the pand problem fixed, therefore
+ I'll undefine BROKEN_PAND by default.
+*/
+
+#ifndef _MMX_H
+#define _MMX_H
+
+
+/* Warning: at this writing, the version of GAS packaged
+ with most Linux distributions does not handle the
+ parallel AND operation mnemonic correctly. If the
+ symbol BROKEN_PAND is defined, a slower alternative
+ coding will be used. If execution of mmxtest results
+ in an illegal instruction fault, define this symbol.
+*/
+#undef BROKEN_PAND
+
+
+/* The type of an value that fits in an MMX register
+ (note that long long constant values MUST be suffixed
+ by LL and unsigned long long values by ULL, lest
+ they be truncated by the compiler)
+*/
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} __attribute__ ((aligned (8))) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+#if 0
+/* Function to test if multimedia instructions are supported...
+*/
+inline extern int
+mm_support(void)
+{
+ /* Returns 1 if MMX instructions are supported,
+ 3 if Cyrix MMX and Extended MMX instructions are supported
+ 5 if AMD MMX and 3DNow! instructions are supported
+ 0 if hardware does not support any of these
+ */
+ register int rval = 0;
+
+ __asm__ __volatile__ (
+ /* See if CPUID instruction is supported ... */
+ /* ... Get copies of EFLAGS into eax and ecx */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t"
+
+ /* ... Toggle the ID bit in one copy and store */
+ /* to the EFLAGS reg */
+ "xorl $0x200000, %%eax\n\t"
+ "push %%eax\n\t"
+ "popf\n\t"
+
+ /* ... Get the (hopefully modified) EFLAGS */
+ "pushf\n\t"
+ "popl %%eax\n\t"
+
+ /* ... Compare and test result */
+ "xorl %%eax, %%ecx\n\t"
+ "testl $0x200000, %%ecx\n\t"
+ "jz NotSupported1\n\t" /* CPUID not supported */
+
+
+ /* Get standard CPUID information, and
+ go to a specific vendor section */
+ "movl $0, %%eax\n\t"
+ "cpuid\n\t"
+
+ /* Check for Intel */
+ "cmpl $0x756e6547, %%ebx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x49656e69, %%edx\n\t"
+ "jne TryAMD\n\t"
+ "cmpl $0x6c65746e, %%ecx\n"
+ "jne TryAMD\n\t"
+ "jmp Intel\n\t"
+
+ /* Check for AMD */
+ "\nTryAMD:\n\t"
+ "cmpl $0x68747541, %%ebx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x69746e65, %%edx\n\t"
+ "jne TryCyrix\n\t"
+ "cmpl $0x444d4163, %%ecx\n"
+ "jne TryCyrix\n\t"
+ "jmp AMD\n\t"
+
+ /* Check for Cyrix */
+ "\nTryCyrix:\n\t"
+ "cmpl $0x69727943, %%ebx\n\t"
+ "jne NotSupported2\n\t"
+ "cmpl $0x736e4978, %%edx\n\t"
+ "jne NotSupported3\n\t"
+ "cmpl $0x64616574, %%ecx\n\t"
+ "jne NotSupported4\n\t"
+ /* Drop through to Cyrix... */
+
+
+ /* Cyrix Section */
+ /* See if extended CPUID level 80000001 is supported */
+ /* The value of CPUID/80000001 for the 6x86MX is undefined
+ according to the Cyrix CPU Detection Guide (Preliminary
+ Rev. 1.01 table 1), so we'll check the value of eax for
+ CPUID/0 to see if standard CPUID level 2 is supported.
+ According to the table, the only CPU which supports level
+ 2 is also the only one which supports extended CPUID levels.
+ */
+ "cmpl $0x2, %%eax\n\t"
+ "jne MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported (in theory), so get extended
+ features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%eax\n\t" /* Test for MMX */
+ "jz NotSupported5\n\t" /* MMX not supported */
+ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
+ "jnz EMMXSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "EMMXSupported:\n\t"
+ "movl $3, %0:\n\n\t" /* EMMX and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* AMD Section */
+ "AMD:\n\t"
+
+ /* See if extended CPUID is supported */
+ "movl $0x80000000, %%eax\n\t"
+ "cpuid\n\t"
+ "cmpl $0x80000000, %%eax\n\t"
+ "jl MMXtest\n\t" /* Use standard CPUID instead */
+
+ /* Extended CPUID supported, so get extended features */
+ "movl $0x80000001, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported6\n\t" /* MMX not supported */
+ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
+ "jnz ThreeDNowSupported\n\t"
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\n"
+ "ThreeDNowSupported:\n\t"
+ "movl $5, %0:\n\n\t" /* 3DNow! and MMX Supported */
+ "jmp Return\n\t"
+
+
+ /* Intel Section */
+ "Intel:\n\t"
+
+ /* Check for MMX */
+ "MMXtest:\n\t"
+ "movl $1, %%eax\n\t"
+ "cpuid\n\t"
+ "testl $0x00800000, %%edx\n\t" /* Test for MMX */
+ "jz NotSupported7\n\t" /* MMX Not supported */
+ "movl $1, %0:\n\n\t" /* MMX Supported */
+ "jmp Return\n\t"
+
+ /* Nothing supported */
+ "\nNotSupported1:\n\t"
+ "#movl $101, %0:\n\n\t"
+ "\nNotSupported2:\n\t"
+ "#movl $102, %0:\n\n\t"
+ "\nNotSupported3:\n\t"
+ "#movl $103, %0:\n\n\t"
+ "\nNotSupported4:\n\t"
+ "#movl $104, %0:\n\n\t"
+ "\nNotSupported5:\n\t"
+ "#movl $105, %0:\n\n\t"
+ "\nNotSupported6:\n\t"
+ "#movl $106, %0:\n\n\t"
+ "\nNotSupported7:\n\t"
+ "#movl $107, %0:\n\n\t"
+ "movl $0, %0:\n\n\t"
+
+ "Return:\n\t"
+ : "=a" (rval)
+ : /* no input */
+ : "eax", "ebx", "ecx", "edx"
+ );
+
+ /* Return */
+ return(rval);
+}
+
+/* Function to test if mmx instructions are supported...
+*/
+inline extern int
+mmx_ok(void)
+{
+ /* Returns 1 if MMX instructions are supported, 0 otherwise */
+ return ( mm_support() & 0x1 );
+}
+#endif
+
+/* Helper functions for the instruction macros that follow...
+ (note that memory-to-register, m2r, instructions are nearly
+ as efficient as register-to-register, r2r, instructions;
+ however, memory-to-memory instructions are really simulated
+ as a convenience, and are only 1/3 as efficient)
+*/
+#ifdef MMX_TRACE
+
+/* Include the stuff for printing a trace to stderr...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace.uq = (imm); \
+ printf(#op "_i2r(" #imm "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "y" (imm)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2r(op, mem, reg) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mem); \
+ printf(#op "_m2r(" #mem "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "y" (mem)); \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#reg "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2m(op, reg, mem) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #reg ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2m(" #reg "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=y" (mem) \
+ : /* nothing */ ); \
+ mmx_trace = (mem); \
+ printf(#mem "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_r2r(op, regs, regd) \
+ { \
+ mmx_t mmx_trace; \
+ __asm__ __volatile__ ("movq %%" #regs ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#op "_r2r(" #regs "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \
+ __asm__ __volatile__ ("movq %%" #regd ", %0" \
+ : "=y" (mmx_trace) \
+ : /* nothing */ ); \
+ printf(#regd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#define mmx_m2m(op, mems, memd) \
+ { \
+ mmx_t mmx_trace; \
+ mmx_trace = (mems); \
+ printf(#op "_m2m(" #mems "=0x%08x%08x, ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x) => ", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=y" (memd) \
+ : "y" (mems)); \
+ mmx_trace = (memd); \
+ printf(#memd "=0x%08x%08x\n", \
+ mmx_trace.d[1], mmx_trace.d[0]); \
+ }
+
+#else
+
+/* These macros are a lot simpler without the tracing...
+*/
+
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "y" (imm) )
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define mmx_m2m(op, mems, memd) \
+ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \
+ #op " %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=y" (memd) \
+ : "y" (mems))
+
+#endif
+
+
+/* 1x64 MOVe Quadword
+ (this is both a load and a store...
+ in fact, it is the only way to store)
+*/
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+#define movq(vars, vard) \
+ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \
+ "movq %%mm0, %0" \
+ : "=y" (vard) \
+ : "y" (vars))
+
+
+/* 1x32 MOVe Doubleword
+ (like movq, this is both load and store...
+ but is most useful for moving things between
+ mmx registers and ordinary registers)
+*/
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+#define movd(vars, vard) \
+ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \
+ "movd %%mm0, %0" \
+ : "=y" (vard) \
+ : "y" (vars))
+
+
+/* 2x32, 4x16, and 8x8 Parallel ADDs
+*/
+#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
+#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
+#define paddd(vars, vard) mmx_m2m(paddd, vars, vard)
+
+#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
+#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
+#define paddw(vars, vard) mmx_m2m(paddw, vars, vard)
+
+#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
+#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
+#define paddb(vars, vard) mmx_m2m(paddb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic
+*/
+#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
+#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
+#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard)
+
+#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
+#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
+#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic
+*/
+#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
+#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
+#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard)
+
+#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
+#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
+#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel SUBs
+*/
+#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
+#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
+#define psubd(vars, vard) mmx_m2m(psubd, vars, vard)
+
+#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
+#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
+#define psubw(vars, vard) mmx_m2m(psubw, vars, vard)
+
+#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
+#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
+#define psubb(vars, vard) mmx_m2m(psubb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic
+*/
+#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
+#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
+#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard)
+
+#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
+#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
+#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard)
+
+
+/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic
+*/
+#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
+#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
+#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard)
+
+#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
+#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
+#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard)
+
+
+/* 4x16 Parallel MULs giving Low 4x16 portions of results
+*/
+#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
+#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
+#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard)
+
+
+/* 4x16 Parallel MULs giving High 4x16 portions of results
+*/
+#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
+#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
+#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard)
+
+
+/* 4x16->2x32 Parallel Mul-ADD
+ (muls like pmullw, then adds adjacent 16-bit fields
+ in the multiply result to make the final 2x32 result)
+*/
+#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
+#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
+#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard)
+
+
+/* 1x64 bitwise AND
+*/
+#ifdef BROKEN_PAND
+#define pand_m2r(var, reg) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, reg); \
+ mmx_m2r(pandn, var, reg); \
+ }
+#define pand_r2r(regs, regd) \
+ { \
+ mmx_m2r(pandn, (mmx_t) -1LL, regd); \
+ mmx_r2r(pandn, regs, regd) \
+ }
+#define pand(vars, vard) \
+ { \
+ movq_m2r(vard, mm0); \
+ mmx_m2r(pandn, (mmx_t) -1LL, mm0); \
+ mmx_m2r(pandn, vars, mm0); \
+ movq_r2m(mm0, vard); \
+ }
+#else
+#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
+#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
+#define pand(vars, vard) mmx_m2m(pand, vars, vard)
+#endif
+
+
+/* 1x64 bitwise AND with Not the destination
+*/
+#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
+#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
+#define pandn(vars, vard) mmx_m2m(pandn, vars, vard)
+
+
+/* 1x64 bitwise OR
+*/
+#define por_m2r(var, reg) mmx_m2r(por, var, reg)
+#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
+#define por(vars, vard) mmx_m2m(por, vars, vard)
+
+
+/* 1x64 bitwise eXclusive OR
+*/
+#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
+#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
+#define pxor(vars, vard) mmx_m2m(pxor, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
+#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard)
+
+#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
+#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard)
+
+#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
+#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard)
+
+
+/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than
+ (resulting fields are either 0 or -1)
+*/
+#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
+#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard)
+
+#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
+#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard)
+
+#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
+#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical
+*/
+#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
+#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
+#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
+#define psllq(vars, vard) mmx_m2m(psllq, vars, vard)
+
+#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
+#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
+#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
+#define pslld(vars, vard) mmx_m2m(pslld, vars, vard)
+
+#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
+#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
+#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
+#define psllw(vars, vard) mmx_m2m(psllw, vars, vard)
+
+
+/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical
+*/
+#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
+#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
+#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
+#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard)
+
+#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
+#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
+#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
+#define psrld(vars, vard) mmx_m2m(psrld, vars, vard)
+
+#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
+#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
+#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
+#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard)
+
+
+/* 2x32 and 4x16 Parallel Shift Right Arithmetic
+*/
+#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
+#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
+#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
+#define psrad(vars, vard) mmx_m2m(psrad, vars, vard)
+
+#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
+#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
+#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
+#define psraw(vars, vard) mmx_m2m(psraw, vars, vard)
+
+
+/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
+#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
+#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard)
+
+#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
+#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
+#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard)
+
+
+/* 4x16->8x8 PACK and Unsigned Saturate
+ (packs source and dest fields into dest in that order)
+*/
+#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
+#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
+#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low
+ (interleaves low half of dest with low half of source
+ as padding in each result field)
+*/
+#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
+#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
+#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard)
+
+#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
+#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
+#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard)
+
+#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
+#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
+#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard)
+
+
+/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High
+ (interleaves high half of dest with high half of source
+ as padding in each result field)
+*/
+#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
+#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
+#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard)
+
+#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
+#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
+#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard)
+
+#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
+#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
+#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard)
+
+
+/* Empty MMx State
+ (used to clean-up when going from mmx to float use
+ of the registers that are shared by both; note that
+ there is no float-to-mmx operation needed, because
+ only the float tag word info is corruptible)
+*/
+#ifdef MMX_TRACE
+
+#define emms() \
+ { \
+ printf("emms()\n"); \
+ __asm__ __volatile__ ("emms"); \
+ }
+
+#else
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#endif
+
+#endif
+
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents.c
new file mode 100644
index 0000000..788c794
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents.c
@@ -0,0 +1,382 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+ Copyright (C) 2002 Greg Haerr <greg@censoft.com>
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_keysym.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nxevents_c.h"
+#include "SDL_nximage_c.h"
+
+// The translation tables from a nanox keysym to a SDL keysym
+static SDLKey NX_NONASCII_keymap [MWKEY_LAST + 1] ;
+
+void NX_InitOSKeymap (_THIS)
+{
+ int i ;
+
+ Dprintf ("enter NX_InitOSKeymap\n") ;
+
+ // Map the nanox scancodes to SDL keysyms
+ for (i = 0; i < SDL_arraysize (NX_NONASCII_keymap); ++ i)
+ NX_NONASCII_keymap [i] = SDLK_UNKNOWN ;
+
+ NX_NONASCII_keymap [MWKEY_LEFT & 0xFF] = SDLK_LEFT ;
+ NX_NONASCII_keymap [MWKEY_RIGHT & 0xFF] = SDLK_RIGHT ;
+ NX_NONASCII_keymap [MWKEY_UP & 0xFF] = SDLK_UP ;
+ NX_NONASCII_keymap [MWKEY_DOWN & 0xFF] = SDLK_DOWN ;
+ NX_NONASCII_keymap [MWKEY_INSERT & 0xFF] = SDLK_INSERT ;
+ NX_NONASCII_keymap [MWKEY_DELETE & 0xFF] = SDLK_DELETE ;
+ NX_NONASCII_keymap [MWKEY_HOME & 0xFF] = SDLK_HOME ;
+ NX_NONASCII_keymap [MWKEY_END & 0xFF] = SDLK_END ;
+ NX_NONASCII_keymap [MWKEY_PAGEUP & 0xFF] = SDLK_PAGEUP ;
+ NX_NONASCII_keymap [MWKEY_PAGEDOWN & 0xFF] = SDLK_PAGEDOWN ;
+
+ NX_NONASCII_keymap [MWKEY_KP0 & 0xFF] = SDLK_KP0 ;
+ NX_NONASCII_keymap [MWKEY_KP1 & 0xFF] = SDLK_KP1 ;
+ NX_NONASCII_keymap [MWKEY_KP2 & 0xFF] = SDLK_KP2 ;
+ NX_NONASCII_keymap [MWKEY_KP3 & 0xFF] = SDLK_KP3 ;
+ NX_NONASCII_keymap [MWKEY_KP4 & 0xFF] = SDLK_KP4 ;
+ NX_NONASCII_keymap [MWKEY_KP5 & 0xFF] = SDLK_KP5 ;
+ NX_NONASCII_keymap [MWKEY_KP6 & 0xFF] = SDLK_KP6 ;
+ NX_NONASCII_keymap [MWKEY_KP7 & 0xFF] = SDLK_KP7 ;
+ NX_NONASCII_keymap [MWKEY_KP8 & 0xFF] = SDLK_KP8 ;
+ NX_NONASCII_keymap [MWKEY_KP9 & 0xFF] = SDLK_KP9 ;
+ NX_NONASCII_keymap [MWKEY_KP_PERIOD & 0xFF] = SDLK_KP_PERIOD ;
+ NX_NONASCII_keymap [MWKEY_KP_DIVIDE & 0xFF] = SDLK_KP_DIVIDE ;
+ NX_NONASCII_keymap [MWKEY_KP_MULTIPLY & 0xFF] = SDLK_KP_MULTIPLY ;
+ NX_NONASCII_keymap [MWKEY_KP_MINUS & 0xFF] = SDLK_KP_MINUS ;
+ NX_NONASCII_keymap [MWKEY_KP_PLUS & 0xFF] = SDLK_KP_PLUS ;
+ NX_NONASCII_keymap [MWKEY_KP_ENTER & 0xFF] = SDLK_KP_ENTER ;
+ NX_NONASCII_keymap [MWKEY_KP_EQUALS & 0xFF] = SDLK_KP_EQUALS ;
+
+ NX_NONASCII_keymap [MWKEY_F1 & 0xFF] = SDLK_F1 ;
+ NX_NONASCII_keymap [MWKEY_F2 & 0xFF] = SDLK_F2 ;
+ NX_NONASCII_keymap [MWKEY_F3 & 0xFF] = SDLK_F3 ;
+ NX_NONASCII_keymap [MWKEY_F4 & 0xFF] = SDLK_F4 ;
+ NX_NONASCII_keymap [MWKEY_F5 & 0xFF] = SDLK_F5 ;
+ NX_NONASCII_keymap [MWKEY_F6 & 0xFF] = SDLK_F6 ;
+ NX_NONASCII_keymap [MWKEY_F7 & 0xFF] = SDLK_F7 ;
+ NX_NONASCII_keymap [MWKEY_F8 & 0xFF] = SDLK_F8 ;
+ NX_NONASCII_keymap [MWKEY_F9 & 0xFF] = SDLK_F9 ;
+ NX_NONASCII_keymap [MWKEY_F10 & 0xFF] = SDLK_F10 ;
+ NX_NONASCII_keymap [MWKEY_F11 & 0xFF] = SDLK_F11 ;
+ NX_NONASCII_keymap [MWKEY_F12 & 0xFF] = SDLK_F12 ;
+
+ NX_NONASCII_keymap [MWKEY_NUMLOCK & 0xFF] = SDLK_NUMLOCK ;
+ NX_NONASCII_keymap [MWKEY_CAPSLOCK & 0xFF] = SDLK_CAPSLOCK ;
+ NX_NONASCII_keymap [MWKEY_SCROLLOCK & 0xFF] = SDLK_SCROLLOCK ;
+ NX_NONASCII_keymap [MWKEY_LSHIFT & 0xFF] = SDLK_LSHIFT ;
+ NX_NONASCII_keymap [MWKEY_RSHIFT & 0xFF] = SDLK_RSHIFT ;
+ NX_NONASCII_keymap [MWKEY_LCTRL & 0xFF] = SDLK_LCTRL ;
+ NX_NONASCII_keymap [MWKEY_RCTRL & 0xFF] = SDLK_RCTRL ;
+ NX_NONASCII_keymap [MWKEY_LALT & 0xFF] = SDLK_LALT ;
+ NX_NONASCII_keymap [MWKEY_RALT & 0xFF] = SDLK_RALT ;
+ NX_NONASCII_keymap [MWKEY_LMETA & 0xFF] = SDLK_LMETA ;
+ NX_NONASCII_keymap [MWKEY_RMETA & 0xFF] = SDLK_RMETA ;
+ NX_NONASCII_keymap [MWKEY_ALTGR & 0xFF] = SDLK_MODE ;
+
+ NX_NONASCII_keymap [MWKEY_PRINT & 0xFF] = SDLK_PRINT ;
+ NX_NONASCII_keymap [MWKEY_SYSREQ & 0xFF] = SDLK_SYSREQ ;
+ NX_NONASCII_keymap [MWKEY_PAUSE & 0xFF] = SDLK_PAUSE ;
+ NX_NONASCII_keymap [MWKEY_BREAK & 0xFF] = SDLK_BREAK ;
+ NX_NONASCII_keymap [MWKEY_MENU & 0xFF] = SDLK_MENU ;
+
+ Dprintf ("leave NX_InitOSKeymap\n") ;
+}
+
+SDL_keysym * NX_TranslateKey (GR_EVENT_KEYSTROKE * keystroke, SDL_keysym * keysym)
+{
+ GR_KEY ch = keystroke -> ch ;
+
+ Dprintf ("enter NX_TranslateKey\n") ;
+
+ keysym -> scancode = keystroke -> scancode ;
+ keysym -> sym = SDLK_UNKNOWN ;
+
+ if (ch & MWKEY_NONASCII_MASK) {
+ keysym -> sym = NX_NONASCII_keymap [ch & 0xFF] ;
+ } else {
+ keysym -> sym = ch & 0x7F ;
+ }
+
+ keysym -> mod = KMOD_NONE ;
+
+#if 1 // Retrieve more mode information
+ {
+ GR_KEYMOD mod = keystroke -> modifiers ;
+
+ if (mod & MWKMOD_LSHIFT)
+ keysym -> mod |= KMOD_LSHIFT ;
+ if (mod & MWKMOD_RSHIFT)
+ keysym -> mod |= KMOD_RSHIFT ;
+ if (mod & MWKMOD_LCTRL)
+ keysym -> mod |= KMOD_LCTRL ;
+ if (mod & MWKMOD_RCTRL)
+ keysym -> mod |= KMOD_RCTRL ;
+ if (mod & MWKMOD_LALT)
+ keysym -> mod |= KMOD_LALT ;
+ if (mod & MWKMOD_RALT)
+ keysym -> mod |= KMOD_RALT ;
+ if (mod & MWKMOD_LMETA)
+ keysym -> mod |= KMOD_LMETA ;
+ if (mod & MWKMOD_RMETA)
+ keysym -> mod |= KMOD_RMETA ;
+ if (mod & MWKMOD_NUM)
+ keysym -> mod |= KMOD_NUM ;
+ if (mod & MWKMOD_CAPS)
+ keysym -> mod |= KMOD_CAPS ;
+ if (mod & MWKMOD_ALTGR)
+ keysym -> mod |= KMOD_MODE ;
+ }
+#endif
+
+ keysym -> unicode = ch ;
+
+ Dprintf ("leave NX_TranslateKey\n") ;
+ return keysym ;
+}
+
+static int check_boundary (_THIS, int x, int y)
+{
+ if (x < OffsetX || y < OffsetY || x > OffsetX + this -> screen -> w ||
+ y > OffsetY + this -> screen -> h)
+ return 0 ;
+
+ return 1 ;
+}
+
+void NX_PumpEvents (_THIS)
+{
+ GR_EVENT event ;
+ static GR_BUTTON last_button_down = 0 ;
+
+ GrCheckNextEvent (& event) ;
+ while (event.type != GR_EVENT_TYPE_NONE) {
+
+ // dispatch event
+ switch (event.type) {
+ case GR_EVENT_TYPE_MOUSE_ENTER :
+ {
+ Dprintf ("mouse enter\n") ;
+ SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_MOUSE_EXIT :
+ {
+ Dprintf ("mouse exit\n") ;
+ SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_FOCUS_IN :
+ {
+ Dprintf ("focus in\n") ;
+ SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_FOCUS_OUT :
+ {
+ Dprintf ("focus out\n") ;
+ SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_MOUSE_MOTION :
+ {
+ Dprintf ("mouse motion\n") ;
+
+ if (SDL_VideoSurface) {
+ if (currently_fullscreen) {
+ if (check_boundary (this, event.button.x, event.button.y)) {
+ SDL_PrivateMouseMotion (0, 0, event.button.x - OffsetX,
+ event.button.y - OffsetY) ;
+ }
+ } else {
+ SDL_PrivateMouseMotion (0, 0, event.button.x, event.button.y) ;
+ }
+ }
+ break ;
+ }
+
+ case GR_EVENT_TYPE_BUTTON_DOWN :
+ {
+ int button = event.button.buttons ;
+
+ Dprintf ("button down\n") ;
+
+ switch (button) {
+ case MWBUTTON_L :
+ button = 1 ;
+ break ;
+ case MWBUTTON_M :
+ button = 2 ;
+ break ;
+ case MWBUTTON_R :
+ button = 3 ;
+ break ;
+ default :
+ button = 0 ;
+ }
+ last_button_down = button ;
+
+ if (currently_fullscreen) {
+ if (check_boundary (this, event.button.x, event.button.y)) {
+ SDL_PrivateMouseButton (SDL_PRESSED, button,
+ event.button.x - OffsetX, event.button.y - OffsetY) ;
+ }
+ } else {
+ SDL_PrivateMouseButton (SDL_PRESSED, button,
+ event.button.x, event.button.y) ;
+ }
+ break ;
+ }
+
+ // do not konw which button is released
+ case GR_EVENT_TYPE_BUTTON_UP :
+ {
+ Dprintf ("button up\n") ;
+
+ if (currently_fullscreen) {
+ if (check_boundary (this, event.button.x, event.button.y)) {
+ SDL_PrivateMouseButton (SDL_RELEASED, last_button_down,
+ event.button.x - OffsetX, event.button.y - OffsetY) ;
+ }
+ } else {
+ SDL_PrivateMouseButton (SDL_RELEASED, last_button_down,
+ event.button.x, event.button.y) ;
+ }
+ last_button_down = 0 ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_KEY_DOWN :
+ {
+ SDL_keysym keysym ;
+
+ Dprintf ("key down\n") ;
+ SDL_PrivateKeyboard (SDL_PRESSED,
+ NX_TranslateKey (& event.keystroke, & keysym)) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_KEY_UP :
+ {
+ SDL_keysym keysym ;
+
+ Dprintf ("key up\n") ;
+ SDL_PrivateKeyboard (SDL_RELEASED,
+ NX_TranslateKey (& event.keystroke, & keysym)) ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_CLOSE_REQ :
+ {
+ Dprintf ("close require\n") ;
+ SDL_PrivateQuit () ;
+ break ;
+ }
+
+ case GR_EVENT_TYPE_EXPOSURE :
+ {
+ Dprintf ("event_type_exposure\n") ;
+ if (SDL_VideoSurface) {
+ NX_RefreshDisplay (this) ;//, & event.exposure) ;
+ }
+ break ;
+ }
+
+ case GR_EVENT_TYPE_UPDATE :
+ {
+ switch (event.update.utype) {
+ case GR_UPDATE_MAP :
+ {
+ Dprintf ("GR_UPDATE_MAP\n") ;
+ // If we're not active, make ourselves active
+ if (!(SDL_GetAppState () & SDL_APPACTIVE)) {
+ // Send an internal activate event
+ SDL_PrivateAppActive (1, SDL_APPACTIVE) ;
+ }
+ if (SDL_VideoSurface) {
+ NX_RefreshDisplay (this) ;
+ }
+ break ;
+ }
+
+ case GR_UPDATE_UNMAP :
+ case GR_UPDATE_UNMAPTEMP :
+ {
+ Dprintf ("GR_UPDATE_UNMAP or GR_UPDATE_UNMAPTEMP\n") ;
+ // If we're active, make ourselves inactive
+ if (SDL_GetAppState () & SDL_APPACTIVE) {
+ // Send an internal deactivate event
+ SDL_PrivateAppActive (0, SDL_APPACTIVE | SDL_APPINPUTFOCUS) ;
+ }
+ break ;
+ }
+
+ case GR_UPDATE_SIZE :
+ {
+ Dprintf ("GR_UPDATE_SIZE\n") ;
+ SDL_PrivateResize (event.update.width, event.update.height) ;
+ break ;
+ }
+
+ case GR_UPDATE_MOVE :
+ case GR_UPDATE_REPARENT :
+ {
+ Dprintf ("GR_UPDATE_MOVE or GR_UPDATE_REPARENT\n") ;
+#ifdef ENABLE_NANOX_DIRECT_FB
+ if (Clientfb) {
+ /* Get current window position and fb pointer*/
+ if (currently_fullscreen)
+ GrGetWindowFBInfo(FSwindow, &fbinfo);
+ else
+ GrGetWindowFBInfo(SDL_Window, &fbinfo);
+ }
+#endif
+ break ;
+ }
+
+ default :
+ Dprintf ("unknown GR_EVENT_TYPE_UPDATE\n") ;
+ break ;
+ }
+ break ;
+ }
+
+ default :
+ {
+ Dprintf ("pump event default\n") ;
+ }
+ }
+
+ GrCheckNextEvent (& event) ;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents_c.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents_c.h
new file mode 100644
index 0000000..b3b4f97
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxevents_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_nxvideo.h"
+
+// Functions to be exported
+extern void NX_InitOSKeymap (_THIS) ;
+extern void NX_PumpEvents (_THIS) ;
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage.c
new file mode 100644
index 0000000..23d3157
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage.c
@@ -0,0 +1,230 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+ Copyright (C) 2002 Greg Haerr <greg@censoft.com>
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_nximage_c.h"
+
+void NX_NormalUpdate (_THIS, int numrects, SDL_Rect * rects)
+{
+ int i, j, xinc, yinc, destinc, rowinc ;
+ int x, y, w, h ;
+ unsigned char * src = NULL, * dest = NULL ;
+
+ Dprintf ("enter NX_NormalUpdate\n") ;
+
+ /* These are the values for the incoming image */
+ xinc = this -> screen -> format -> BytesPerPixel ;
+ yinc = this -> screen -> pitch ;
+
+ for (i = 0; i < numrects; ++ i) {
+ x = rects [i].x, y = rects [i].y ;
+ w = rects [i].w, h = rects [i].h ;
+ src = SDL_Image + y * yinc + x * xinc ;
+#ifdef ENABLE_NANOX_DIRECT_FB
+ if (Clientfb) {
+ if (currently_fullscreen)
+ dest = fbinfo.winpixels + (((y+OffsetY) * fbinfo.pitch) +
+ ((x+OffsetX) * fbinfo.bytespp));
+ else
+ dest = fbinfo.winpixels + ((y * fbinfo.pitch) + (x * fbinfo.bytespp));
+ destinc = fbinfo.pitch;
+ }
+ else
+#endif
+ {
+ dest = Image_buff ;
+ destinc = w * xinc ;
+ }
+ rowinc = w * xinc;
+
+ // apply GammaRamp table
+ if ((pixel_type == MWPF_TRUECOLOR0888 || pixel_type == MWPF_TRUECOLOR888)
+ && GammaRamp_R && GammaRamp_G && GammaRamp_B) {
+ Uint8 * ptrsrc ;
+ Uint8 * ptrdst ;
+ int k ;
+
+ for (j = h; j > 0; -- j, src += yinc, dest += destinc) {
+ ptrsrc = src ;
+ ptrdst = dest ;
+ for (k = w; k > 0; -- k) {
+ *ptrdst++ = GammaRamp_B [*ptrsrc++] >> 8;
+ *ptrdst++ = GammaRamp_G [*ptrsrc++] >> 8;
+ *ptrdst++ = GammaRamp_R [*ptrsrc++] >> 8;
+ *ptrdst++ = 0;
+ ++ptrsrc;
+ }
+ }
+ }
+#if 1 /* This is needed for microwindows 0.90 or older */
+ else if (pixel_type == MWPF_TRUECOLOR0888 || pixel_type == MWPF_TRUECOLOR888) {
+ Uint8 * ptrsrc ;
+ Uint8 * ptrdst ;
+ int k ;
+
+ for (j = h; j > 0; -- j, src += yinc, dest += destinc) {
+ ptrsrc = src ;
+ ptrdst = dest ;
+ for (k = w; k > 0; -- k) {
+ *ptrdst++ = *ptrsrc++;
+ *ptrdst++ = *ptrsrc++;
+ *ptrdst++ = *ptrsrc++;
+ *ptrdst++ = 0;
+ ++ptrsrc;
+ }
+ }
+ }
+#endif
+ else
+ {
+ for (j = h; j > 0; -- j, src += yinc, dest += destinc)
+ SDL_memcpy (dest, src, rowinc) ;
+ }
+ if (!Clientfb) {
+ if (currently_fullscreen) {
+ GrArea (FSwindow, SDL_GC, x + OffsetX, y + OffsetY, w, h, Image_buff,
+ pixel_type) ;
+ } else {
+ GrArea (SDL_Window, SDL_GC, x, y, w, h, Image_buff, pixel_type) ;
+ }
+ }
+ }
+ GrFlush();
+
+ Dprintf ("leave NX_NormalUpdate\n") ;
+}
+
+int NX_SetupImage (_THIS, SDL_Surface * screen)
+{
+ int size = screen -> h * screen -> pitch ;
+
+ Dprintf ("enter NX_SetupImage\n") ;
+
+ screen -> pixels = (void *) SDL_malloc (size) ;
+
+ if (!Clientfb) {
+ Image_buff = (unsigned char *) SDL_malloc (size) ;
+ if (screen -> pixels == NULL || Image_buff == NULL) {
+ SDL_free (screen -> pixels) ;
+ SDL_free (Image_buff) ;
+ SDL_OutOfMemory () ;
+ return -1 ;
+ }
+ }
+
+ SDL_Image = (unsigned char *) screen -> pixels ;
+
+ this -> UpdateRects = NX_NormalUpdate ;
+
+ Dprintf ("leave NX_SetupImage\n") ;
+ return 0 ;
+}
+
+void NX_DestroyImage (_THIS, SDL_Surface * screen)
+{
+ Dprintf ("enter NX_DestroyImage\n") ;
+
+ if (SDL_Image) SDL_free (SDL_Image) ;
+ if (Image_buff) SDL_free (Image_buff) ;
+ if (screen) screen -> pixels = NULL ;
+
+ Dprintf ("leave NX_DestroyImage\n") ;
+}
+
+int NX_ResizeImage (_THIS, SDL_Surface * screen, Uint32 flags)
+{
+ int retval ;
+ GR_SCREEN_INFO si ;
+
+ Dprintf ("enter NX_ResizeImage\n") ;
+
+ NX_DestroyImage (this, screen) ;
+ retval = NX_SetupImage (this, screen) ;
+
+ GrGetScreenInfo (& si) ;
+ OffsetX = (si.cols - screen -> w) / 2 ;
+ OffsetY = (si.rows - screen -> h) / 2 ;
+
+#ifdef ENABLE_NANOX_DIRECT_FB
+ if (Clientfb) {
+ /* Get current window position and fb pointer*/
+ if (currently_fullscreen)
+ GrGetWindowFBInfo(FSwindow, &fbinfo);
+ else
+ GrGetWindowFBInfo(SDL_Window, &fbinfo);
+ }
+#endif
+ Dprintf ("leave NX_ResizeImage\n") ;
+ return retval ;
+}
+
+void NX_RefreshDisplay (_THIS)
+{
+ Dprintf ("enter NX_RefreshDisplay\n") ;
+
+ // Don't refresh a display that doesn't have an image (like GL)
+ if (! SDL_Image) {
+ return;
+ }
+
+#ifdef ENABLE_NANOX_DIRECT_FB
+ if (Clientfb) {
+ int j;
+ char *src, *dest = NULL;
+ int xinc, yinc, rowinc;
+
+ GrGetWindowFBInfo(SDL_Window, &fbinfo);
+
+ xinc = this -> screen -> format -> BytesPerPixel ;
+ yinc = this -> screen -> pitch ;
+
+ src = SDL_Image;
+ if (currently_fullscreen)
+ dest = fbinfo.winpixels + ((OffsetY * fbinfo.pitch) +
+ (OffsetX * fbinfo.bytespp));
+ else
+ dest = fbinfo.winpixels;
+ rowinc = xinc * this -> screen -> w;
+
+ for (j = this -> screen -> h; j > 0; -- j, src += yinc, dest += fbinfo.pitch)
+ SDL_memcpy (dest, src, rowinc) ;
+ }
+ else
+#endif
+ {
+ if (currently_fullscreen) {
+ GrArea (FSwindow, SDL_GC, OffsetX, OffsetY, this -> screen -> w,
+ this -> screen -> h, SDL_Image, pixel_type) ;
+ } else {
+ GrArea (SDL_Window, SDL_GC, 0, 0, this -> screen -> w,
+ this -> screen -> h, SDL_Image, pixel_type) ;
+ }
+ }
+ GrFlush();
+
+ Dprintf ("leave NX_RefreshDisplay\n") ;
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage_c.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage_c.h
new file mode 100644
index 0000000..0bf29e5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nximage_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_nxvideo.h"
+
+extern int NX_SetupImage (_THIS, SDL_Surface * screen) ;
+extern void NX_DestroyImage (_THIS, SDL_Surface * screen) ;
+extern int NX_ResizeImage (_THIS, SDL_Surface * screen, Uint32 flags) ;
+
+extern void NX_NormalUpdate (_THIS, int numrects, SDL_Rect * rects) ;
+extern void NX_RefreshDisplay (_THIS) ;
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes.c
new file mode 100644
index 0000000..bcf74e5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes.c
@@ -0,0 +1,84 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_stdinc.h"
+#include "SDL_nxmodes_c.h"
+
+SDL_Rect ** NX_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ return SDL_modelist ;
+
+ if (SDL_Visual.bpp == format -> BitsPerPixel) {
+ return ((SDL_Rect **) -1) ;
+ } else {
+ return ((SDL_Rect **) 0) ;
+ }
+}
+
+void NX_FreeVideoModes (_THIS)
+{
+ int i ;
+
+ if (SDL_modelist) {
+ for (i = 0; SDL_modelist [i]; ++ i) {
+ SDL_free (SDL_modelist [i]) ;
+ }
+ SDL_free (SDL_modelist) ;
+ SDL_modelist = NULL;
+ }
+}
+
+int NX_EnterFullScreen (_THIS)
+{
+ if (! currently_fullscreen) {
+ GR_SCREEN_INFO si ;
+
+ GrGetScreenInfo (& si) ;
+ GrResizeWindow (FSwindow, si.cols, si.rows) ;
+ GrUnmapWindow (SDL_Window) ;
+ GrMapWindow (FSwindow) ;
+ GrRaiseWindow (FSwindow) ;
+ GrSetFocus (FSwindow) ;
+ currently_fullscreen = 1 ;
+ }
+
+ return 1 ;
+}
+
+int NX_LeaveFullScreen (_THIS)
+{
+ if (currently_fullscreen) {
+ GrUnmapWindow (FSwindow) ;
+ GrMapWindow (SDL_Window) ;
+ GrRaiseWindow (SDL_Window) ;
+ GrSetFocus (SDL_Window) ;
+ currently_fullscreen = 0 ;
+ }
+
+ return 0 ;
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes_c.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes_c.h
new file mode 100644
index 0000000..fe2e655
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmodes_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_nxvideo.h"
+#include <SDL.h>
+
+extern SDL_Rect ** NX_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags) ;
+extern void NX_FreeVideoModes (_THIS) ;
+extern int NX_EnterFullScreen (_THIS) ;
+extern int NX_LeaveFullScreen (_THIS) ;
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse.c
new file mode 100644
index 0000000..9c8f382
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse.c
@@ -0,0 +1,79 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nxmouse_c.h"
+
+// The implementation dependent data for the window manager cursor
+struct WMcursor {
+ int unused ;
+} ;
+
+WMcursor * NX_CreateWMCursor (_THIS,
+ Uint8 * data, Uint8 * mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor * cursor ;
+
+ Dprintf ("enter NX_CreateWMCursor\n") ;
+
+ cursor = (WMcursor *) SDL_malloc (sizeof (WMcursor)) ;
+ if (cursor == NULL) {
+ SDL_OutOfMemory () ;
+ return NULL ;
+ }
+
+ Dprintf ("leave NX_CreateWMCursor\n") ;
+ return cursor ;
+}
+
+void NX_FreeWMCursor (_THIS, WMcursor * cursor)
+{
+ Dprintf ("NX_FreeWMCursor\n") ;
+ SDL_free (cursor) ;
+ return ;
+}
+
+void NX_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ GR_WINDOW_INFO info ;
+
+ Dprintf ("enter NX_WarpWMCursor\n") ;
+ SDL_Lock_EventThread () ;
+
+ GrGetWindowInfo (SDL_Window, & info) ;
+ GrMoveCursor (info.x + x, info.y + y) ;
+
+ SDL_Unlock_EventThread () ;
+ Dprintf ("leave NX_WarpWMCursor\n") ;
+}
+
+int NX_ShowWMCursor (_THIS, WMcursor * cursor)
+{
+ Dprintf ("NX_ShowWMCursor\n") ;
+ return 1 ;
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse_c.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse_c.h
new file mode 100644
index 0000000..d7fedb5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxmouse_c.h
@@ -0,0 +1,29 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_nxvideo.h"
+
+extern WMcursor * NX_CreateWMCursor (_THIS, Uint8 * data, Uint8 * mask, int w, int h, int hot_x, int hot_y) ;
+void NX_FreeWMCursor (_THIS, WMcursor * cursor) ;
+extern void NX_WarpWMCursor (_THIS, Uint16 x, Uint16 y) ;
+extern int NX_ShowWMCursor (_THIS, WMcursor * cursor) ;
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.c
new file mode 100644
index 0000000..b188e09
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.c
@@ -0,0 +1,544 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+ Copyright (C) 2002 Greg Haerr <greg@censoft.com>
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_thread.h"
+#include "SDL_video.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#define MWINCLUDECOLORS
+#include "SDL_nxvideo.h"
+#include "SDL_nxmodes_c.h"
+#include "SDL_nxwm_c.h"
+#include "SDL_nxmouse_c.h"
+#include "SDL_nximage_c.h"
+#include "SDL_nxevents_c.h"
+
+// Initialization/Query functions
+static int NX_VideoInit (_THIS, SDL_PixelFormat * vformat) ;
+static SDL_Surface * NX_SetVideoMode (_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags) ;
+static int NX_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors) ;
+static void NX_VideoQuit (_THIS) ;
+static void NX_DestroyWindow (_THIS, SDL_Surface * screen) ;
+static int NX_ToggleFullScreen (_THIS, int on) ;
+static void NX_UpdateMouse (_THIS) ;
+static int NX_SetGammaRamp (_THIS, Uint16 * ramp) ;
+static int NX_GetGammaRamp (_THIS, Uint16 * ramp) ;
+
+// Microwin driver bootstrap functions
+static int NX_Available ()
+{
+ Dprintf ("enter NX_Available\n") ;
+
+ if (GrOpen () < 0) return 0 ;
+ GrClose () ;
+
+ Dprintf ("leave NX_Available\n") ;
+ return 1 ;
+}
+
+static void NX_DeleteDevice (SDL_VideoDevice * device)
+{
+ Dprintf ("enter NX_DeleteDevice\n") ;
+
+ if (device) {
+ if (device -> hidden) SDL_free (device -> hidden) ;
+ if (device -> gl_data) SDL_free (device -> gl_data) ;
+ SDL_free (device) ;
+ }
+
+ Dprintf ("leave NX_DeleteDevice\n") ;
+}
+
+static SDL_VideoDevice * NX_CreateDevice (int devindex)
+{
+ SDL_VideoDevice * device ;
+
+ Dprintf ("enter NX_CreateDevice\n") ;
+
+ // Initialize all variables that we clean on shutdown
+ device = (SDL_VideoDevice *) SDL_malloc (sizeof (SDL_VideoDevice)) ;
+ if (device) {
+ SDL_memset (device, 0, (sizeof * device)) ;
+ device -> hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc ((sizeof * device -> hidden)) ;
+ device -> gl_data = NULL ;
+ }
+ if ((device == NULL) || (device -> hidden == NULL)) {
+ SDL_OutOfMemory () ;
+ NX_DeleteDevice (device) ;
+ return 0 ;
+ }
+ SDL_memset (device -> hidden, 0, (sizeof * device -> hidden)) ;
+
+ // Set the function pointers
+ device -> VideoInit = NX_VideoInit ;
+ device -> ListModes = NX_ListModes ;
+ device -> SetVideoMode = NX_SetVideoMode ;
+ device -> ToggleFullScreen = NX_ToggleFullScreen ;
+ device -> UpdateMouse = NX_UpdateMouse ;
+ device -> CreateYUVOverlay = NULL ;
+ device -> SetColors = NX_SetColors ;
+ device -> UpdateRects = NULL ;
+ device -> VideoQuit = NX_VideoQuit;
+ device -> AllocHWSurface = NULL ;
+ device -> CheckHWBlit = NULL ;
+ device -> FillHWRect = NULL ;
+ device -> SetHWColorKey = NULL ;
+ device -> SetHWAlpha = NULL ;
+ device -> LockHWSurface = NULL ;
+ device -> UnlockHWSurface = NULL ;
+ device -> FlipHWSurface = NULL ;
+ device -> FreeHWSurface = NULL ;
+ device -> SetGamma = NULL ;
+ device -> GetGamma = NULL ;
+ device -> SetGammaRamp = NX_SetGammaRamp ;
+ device -> GetGammaRamp = NX_GetGammaRamp ;
+
+#if SDL_VIDEO_OPENGL
+ device -> GL_LoadLibrary = NULL ;
+ device -> GL_GetProcAddress = NULL ;
+ device -> GL_GetAttribute = NULL ;
+ device -> GL_MakeCurrent = NULL ;
+ device -> GL_SwapBuffers = NULL ;
+#endif
+
+ device -> SetIcon = NULL ;
+ device -> SetCaption = NX_SetCaption;
+ device -> IconifyWindow = NULL ;
+ device -> GrabInput = NULL ;
+ device -> GetWMInfo = NX_GetWMInfo ;
+ device -> FreeWMCursor = NX_FreeWMCursor ;
+ device -> CreateWMCursor = NX_CreateWMCursor ;
+ device -> ShowWMCursor = NX_ShowWMCursor ;
+ device -> WarpWMCursor = NX_WarpWMCursor ;
+ device -> CheckMouseMode = NULL ;
+ device -> InitOSKeymap = NX_InitOSKeymap ;
+ device -> PumpEvents = NX_PumpEvents ;
+
+ device -> free = NX_DeleteDevice ;
+
+ Dprintf ("leave NX_CreateDevice\n") ;
+ return device ;
+}
+
+VideoBootStrap NX_bootstrap = {
+ "nanox", "nanox", NX_Available, NX_CreateDevice
+} ;
+
+static void create_aux_windows (_THIS)
+{
+ GR_WM_PROPERTIES props ;
+
+ Dprintf ("enter create_aux_windows\n") ;
+
+ // Don't create any extra windows if we are being managed
+ if (SDL_windowid) {
+ FSwindow = 0 ;
+ return ;
+ }
+
+ if (FSwindow && FSwindow != GR_ROOT_WINDOW_ID) {
+ GrDestroyWindow (FSwindow) ;
+ }
+
+ FSwindow = GrNewWindow (GR_ROOT_WINDOW_ID, 0, 0, 1, 1, 0, BLACK, BLACK) ;
+ props.flags = GR_WM_FLAGS_PROPS ;
+ props.props = GR_WM_PROPS_NODECORATE ;
+ GrSetWMProperties (FSwindow, & props) ;
+
+ GrSelectEvents (FSwindow, (GR_EVENT_MASK_EXPOSURE |
+ GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP |
+ GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT |
+ GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_KEY_UP |
+ GR_EVENT_MASK_MOUSE_ENTER | GR_EVENT_MASK_MOUSE_EXIT |
+ GR_EVENT_MASK_MOUSE_MOTION | GR_EVENT_MASK_UPDATE |
+ GR_EVENT_MASK_CLOSE_REQ)) ;
+
+ Dprintf ("leave create_aux_windows\n") ;
+}
+
+int NX_VideoInit (_THIS, SDL_PixelFormat * vformat)
+{
+ GR_SCREEN_INFO si ;
+
+ Dprintf ("enter NX_VideoInit\n") ;
+
+ if (GrOpen () < 0) {
+ SDL_SetError ("GrOpen() fail") ;
+ return -1 ;
+ }
+
+ // use share memory to speed up
+#ifdef NANOX_SHARE_MEMORY
+ GrReqShmCmds (0xFFFF);
+#endif
+
+ SDL_Window = 0 ;
+ FSwindow = 0 ;
+
+ GammaRamp_R = NULL ;
+ GammaRamp_G = NULL ;
+ GammaRamp_B = NULL ;
+
+ GrGetScreenInfo (& si) ;
+ SDL_Visual.bpp = si.bpp ;
+
+ /* Determine the current screen size */
+ this->info.current_w = si.cols ;
+ this->info.current_h = si.rows ;
+
+ // GetVideoMode
+ SDL_modelist = (SDL_Rect **) SDL_malloc (sizeof (SDL_Rect *) * 2) ;
+ if (SDL_modelist) {
+ SDL_modelist [0] = (SDL_Rect *) SDL_malloc (sizeof(SDL_Rect)) ;
+ if (SDL_modelist [0]) {
+ SDL_modelist [0] -> x = 0 ;
+ SDL_modelist [0] -> y = 0 ;
+ SDL_modelist [0] -> w = si.cols ;
+ SDL_modelist [0] -> h = si.rows ;
+ }
+ SDL_modelist [1] = NULL ;
+ }
+
+ pixel_type = si.pixtype;
+ SDL_Visual.red_mask = si.rmask;
+ SDL_Visual.green_mask = si.gmask;
+ SDL_Visual.blue_mask = si.bmask;
+
+ vformat -> BitsPerPixel = SDL_Visual.bpp ;
+ if (vformat -> BitsPerPixel > 8) {
+ vformat -> Rmask = SDL_Visual.red_mask ;
+ vformat -> Gmask = SDL_Visual.green_mask ;
+ vformat -> Bmask = SDL_Visual.blue_mask ;
+ }
+
+ // See if we have been passed a window to use
+ SDL_windowid = getenv ("SDL_WINDOWID") ;
+
+ // Create the fullscreen (and managed windows : no implement)
+ create_aux_windows (this) ;
+
+ Dprintf ("leave NX_VideoInit\n") ;
+ return 0 ;
+}
+
+void NX_VideoQuit (_THIS)
+{
+ Dprintf ("enter NX_VideoQuit\n") ;
+
+ // Start shutting down the windows
+ NX_DestroyImage (this, this -> screen) ;
+ NX_DestroyWindow (this, this -> screen) ;
+ if (FSwindow && FSwindow != GR_ROOT_WINDOW_ID) {
+ GrDestroyWindow (FSwindow) ;
+ }
+ NX_FreeVideoModes (this) ;
+ SDL_free (GammaRamp_R) ;
+ SDL_free (GammaRamp_G) ;
+ SDL_free (GammaRamp_B) ;
+
+#ifdef ENABLE_NANOX_DIRECT_FB
+ if (Clientfb)
+ GrCloseClientFramebuffer();
+#endif
+ GrClose () ;
+
+ Dprintf ("leave NX_VideoQuit\n") ;
+}
+
+static void NX_DestroyWindow (_THIS, SDL_Surface * screen)
+{
+ Dprintf ("enter NX_DestroyWindow\n") ;
+
+ if (! SDL_windowid) {
+ if (screen && (screen -> flags & SDL_FULLSCREEN)) {
+ screen -> flags &= ~ SDL_FULLSCREEN ;
+ NX_LeaveFullScreen (this) ;
+ }
+
+ // Destroy the output window
+ if (SDL_Window && SDL_Window != GR_ROOT_WINDOW_ID) {
+ GrDestroyWindow (SDL_Window) ;
+ }
+ }
+
+ // Free the graphics context
+ if (! SDL_GC) {
+ GrDestroyGC (SDL_GC) ;
+ SDL_GC = 0;
+ }
+
+ Dprintf ("leave NX_DestroyWindow\n") ;
+}
+
+static int NX_CreateWindow (_THIS, SDL_Surface * screen,
+ int w, int h, int bpp, Uint32 flags)
+{
+ Dprintf ("enter NX_CreateWindow\n") ;
+
+ // If a window is already present, destroy it and start fresh
+ if (SDL_Window && SDL_Window != GR_ROOT_WINDOW_ID) {
+ NX_DestroyWindow (this, screen) ;
+ }
+
+ // See if we have been given a window id
+ if (SDL_windowid) {
+ SDL_Window = SDL_strtol (SDL_windowid, NULL, 0) ;
+ } else {
+ SDL_Window = 0 ;
+ }
+
+ if ( ! SDL_ReallocFormat (screen, bpp, SDL_Visual.red_mask,
+ SDL_Visual.green_mask, SDL_Visual.blue_mask, 0))
+ return -1;
+
+ // Create (or use) the nanox display window
+ if (! SDL_windowid) {
+
+ SDL_Window = GrNewWindow (GR_ROOT_WINDOW_ID, 0, 0, w, h, 0, BLACK, WHITE) ;
+
+ GrSelectEvents (SDL_Window, (GR_EVENT_MASK_EXPOSURE |
+ GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP |
+ GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT |
+ GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_KEY_UP |
+ GR_EVENT_MASK_MOUSE_ENTER | GR_EVENT_MASK_MOUSE_EXIT |
+ GR_EVENT_MASK_MOUSE_MOTION | GR_EVENT_MASK_UPDATE |
+ GR_EVENT_MASK_CLOSE_REQ)) ;
+ }
+
+ /* Create the graphics context here, once we have a window */
+ SDL_GC = GrNewGC () ;
+ if (SDL_GC == 0) {
+ SDL_SetError("Couldn't create graphics context");
+ return(-1);
+ }
+
+ // Map them both and go fullscreen, if requested
+ if (! SDL_windowid) {
+ GrMapWindow (SDL_Window) ;
+ if (flags & SDL_FULLSCREEN) {
+ screen -> flags |= SDL_FULLSCREEN ;
+ NX_EnterFullScreen (this) ;
+ } else {
+ screen -> flags &= ~ SDL_FULLSCREEN ;
+ }
+ }
+
+#ifdef ENABLE_NANOX_DIRECT_FB
+ /* attempt allocating the client side framebuffer */
+ Clientfb = GrOpenClientFramebuffer();
+ /* NULL return will default to using GrArea()*/
+#endif
+
+ Dprintf ("leave NX_CreateWindow\n") ;
+ return 0 ;
+}
+
+SDL_Surface * NX_SetVideoMode (_THIS, SDL_Surface * current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Dprintf ("enter NX_SetVideoMode\n") ;
+
+ // Lock the event thread, in multi-threading environments
+ SDL_Lock_EventThread () ;
+
+ bpp = SDL_Visual.bpp ;
+ if (NX_CreateWindow (this, current, width, height, bpp, flags) < 0) {
+ current = NULL;
+ goto done;
+ }
+
+ if (current -> w != width || current -> h != height) {
+ current -> w = width ;
+ current -> h = height ;
+ current -> pitch = SDL_CalculatePitch (current) ;
+ NX_ResizeImage (this, current, flags) ;
+ }
+
+ /* Clear these flags and set them only if they are in the new set. */
+ current -> flags &= ~(SDL_RESIZABLE|SDL_NOFRAME);
+ current -> flags |= (flags & (SDL_RESIZABLE | SDL_NOFRAME)) ;
+
+ done:
+ SDL_Unlock_EventThread () ;
+
+ Dprintf ("leave NX_SetVideoMode\n") ;
+
+ // We're done!
+ return current ;
+}
+
+// ncolors <= 256
+int NX_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors)
+{
+ int i ;
+ GR_PALETTE pal ;
+
+ Dprintf ("enter NX_SetColors\n") ;
+
+ if (ncolors > 256) return 0 ;
+
+ pal.count = ncolors ;
+ for (i = 0; i < ncolors; ++ i) {
+ pal.palette [i].r = colors [i].r ;
+ pal.palette [i].g = colors [i].g ;
+ pal.palette [i].b = colors [i].b ;
+ }
+ GrSetSystemPalette (firstcolor, & pal) ;
+
+ Dprintf ("leave NX_SetColors\n") ;
+ return 1 ;
+}
+
+static int NX_ToggleFullScreen (_THIS, int on)
+{
+ SDL_Rect rect ;
+ Uint32 event_thread ;
+
+ Dprintf ("enter NX_ToggleFullScreen\n") ;
+
+ // Don't switch if we don't own the window
+ if (SDL_windowid) return 0 ;
+
+ // Don't lock if we are the event thread
+ event_thread = SDL_EventThreadID () ;
+ if (event_thread && (SDL_ThreadID () == event_thread)) {
+ event_thread = 0 ;
+ }
+ if (event_thread) {
+ SDL_Lock_EventThread() ;
+ }
+
+ if (on) {
+ NX_EnterFullScreen (this) ;
+ } else {
+ this -> screen -> flags &= ~ SDL_FULLSCREEN ;
+ NX_LeaveFullScreen (this) ;
+ }
+
+ rect.x = rect.y = 0 ;
+ rect.w = this -> screen -> w, rect.h = this -> screen -> h ;
+ NX_NormalUpdate (this, 1, & rect) ;
+
+ if (event_thread) {
+ SDL_Unlock_EventThread () ;
+ }
+
+ Dprintf ("leave NX_ToggleFullScreen\n") ;
+ return 1 ;
+}
+
+// Update the current mouse state and position
+static void NX_UpdateMouse (_THIS)
+{
+ int x, y ;
+ GR_WINDOW_INFO info ;
+ GR_SCREEN_INFO si ;
+
+
+ Dprintf ("enter NX_UpdateMouse\n") ;
+
+ // Lock the event thread, in multi-threading environments
+ SDL_Lock_EventThread () ;
+
+ GrGetScreenInfo (& si) ;
+ GrGetWindowInfo (SDL_Window, & info) ;
+ x = si.xpos - info.x ;
+ y = si.ypos - info.y ;
+ if (x >= 0 && x <= info.width && y >= 0 && y <= info.height) {
+ SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS) ;
+ SDL_PrivateMouseMotion (0, 0, x, y);
+ } else {
+ SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS) ;
+ }
+
+ SDL_Unlock_EventThread () ;
+ Dprintf ("leave NX_UpdateMouse\n") ;
+}
+
+static int NX_SetGammaRamp (_THIS, Uint16 * ramp)
+{
+ int i ;
+ Uint16 * red, * green, * blue ;
+
+ Dprintf ("enter NX_SetGammaRamp\n") ;
+
+ if (SDL_Visual.bpp != 32 && SDL_Visual.bpp != 24) return -1 ;
+
+ if (! GammaRamp_R) GammaRamp_R = (Uint16 *) SDL_malloc (sizeof (Uint16) * CI_SIZE) ;
+ if (! GammaRamp_G) GammaRamp_G = (Uint16 *) SDL_malloc (sizeof (Uint16) * CI_SIZE) ;
+ if (! GammaRamp_B) GammaRamp_B = (Uint16 *) SDL_malloc (sizeof (Uint16) * CI_SIZE) ;
+ if ((! GammaRamp_R) || (! GammaRamp_G) || (! GammaRamp_B)) {
+ SDL_OutOfMemory () ;
+ return -1 ;
+ }
+
+ for (i = 0; i < CI_SIZE; ++ i)
+ GammaRamp_R [i] = GammaRamp_G [i] = GammaRamp_B [i] = i ;
+
+ red = ramp ;
+ green = ramp + CI_SIZE ;
+ blue = green + CI_SIZE ;
+
+ for (i = 0; i < CI_SIZE; ++ i) {
+ GammaRamp_R [i] = red [i] ;
+ GammaRamp_G [i] = green [i] ;
+ GammaRamp_B [i] = blue [i] ;
+ }
+ SDL_UpdateRect(this->screen, 0, 0, 0, 0);
+
+ Dprintf ("leave NX_SetGammaRamp\n") ;
+ return 0 ;
+}
+
+static int NX_GetGammaRamp (_THIS, Uint16 * ramp)
+{
+ int i ;
+ Uint16 * red, * green, * blue ;
+
+ Dprintf ("enter NX_GetGammaRamp\n") ;
+
+ if (SDL_Visual.bpp != 32 && SDL_Visual.bpp != 24) return -1 ;
+ red = ramp ;
+ green = ramp + CI_SIZE ;
+ blue = green + CI_SIZE ;
+ if (GammaRamp_R && GammaRamp_G && GammaRamp_B) {
+ for (i = 0; i < CI_SIZE; ++ i) {
+ red [i] = GammaRamp_R [i] ;
+ green [i] = GammaRamp_G [i] ;
+ blue [i] = GammaRamp_B [i] ;
+ }
+ } else {
+ for (i = 0; i < CI_SIZE; ++ i)
+ red [i] = green [i] = blue [i] = i ;
+ }
+
+ Dprintf ("leave NX_GetGammaRamp\n") ;
+ return 0 ;
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.h
new file mode 100644
index 0000000..1d858d9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxvideo.h
@@ -0,0 +1,96 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_nxvideo_h
+#define _SDL_nxvideo_h
+
+#include <microwin/nano-X.h>
+
+#include "../SDL_sysvideo.h"
+
+#ifdef ENABLE_NANOX_DEBUG
+#define Dprintf printf
+#else
+#define Dprintf(ignore...)
+#endif
+
+// Hidden "this" pointer for the video functions
+#define _THIS SDL_VideoDevice * this
+
+// Private display data
+typedef struct NX_SDL_VISUAL {
+ int bpp ;
+ Uint32 red_mask ;
+ Uint32 green_mask ;
+ Uint32 blue_mask ;
+} nx_sdl_visual_t ;
+
+struct SDL_PrivateVideoData {
+ GR_WINDOW_ID SDL_Window ;
+ GR_WINDOW_ID FSwindow ;
+ // Flag: true if we have been passed a window
+ char * SDL_windowid ;
+ GR_GC_ID GC ;
+ unsigned char * Image ;
+ unsigned char * Image_buff ; /* for GrArea*/
+ unsigned char * Clientfb; /* for DirectFB*/
+ nx_sdl_visual_t SDL_Visual ;
+ // The current list of available video modes
+ SDL_Rect ** modelist ;
+ int currently_fullscreen ;
+ // for fullscreen
+ int OffsetX, OffsetY ;
+ // for GammaRamp
+ Uint16 * GammaRamp_R, * GammaRamp_G, * GammaRamp_B ;
+ // for GrArea, r_mask, g_mask, b_mask
+ int pixel_type ;
+#ifdef ENABLE_NANOX_DIRECT_FB
+ GR_WINDOW_FB_INFO fbinfo;
+#endif
+} ;
+
+#define SDL_Window (this -> hidden -> SDL_Window)
+#define FSwindow (this -> hidden -> FSwindow)
+#define SDL_windowid (this -> hidden -> SDL_windowid)
+#define SDL_GC (this -> hidden -> GC)
+#define SDL_Image (this -> hidden -> Image)
+#define Image_buff (this -> hidden -> Image_buff)
+#define Clientfb (this -> hidden -> Clientfb)
+#define SDL_Visual (this -> hidden -> SDL_Visual)
+#define SDL_modelist (this -> hidden -> modelist)
+#define currently_fullscreen (this -> hidden -> currently_fullscreen)
+#define OffsetX (this -> hidden -> OffsetX)
+#define OffsetY (this -> hidden -> OffsetY)
+#define GammaRamp_R (this -> hidden -> GammaRamp_R)
+#define GammaRamp_G (this -> hidden -> GammaRamp_G)
+#define GammaRamp_B (this -> hidden -> GammaRamp_B)
+#define pixel_type (this -> hidden -> pixel_type)
+#define fbinfo (this -> hidden -> fbinfo)
+
+#define CI_SIZE 256 // color index size
+
+#endif // _SDL_nxvideo_h
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm.c b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm.c
new file mode 100644
index 0000000..c60ebb0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm.c
@@ -0,0 +1,61 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_syswm.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_nxwm_c.h"
+
+void NX_SetCaption (_THIS, const char * title, const char * icon)
+{
+ Dprintf ("enter NX_SetCaption\n") ;
+
+ // Lock the event thread, in multi-threading environments
+ SDL_Lock_EventThread () ;
+
+ if (SDL_Window)
+ GrSetWindowTitle (SDL_Window, title) ;
+
+ SDL_Unlock_EventThread () ;
+ Dprintf ("leave NX_SetCaption\n") ;
+}
+
+int NX_GetWMInfo (_THIS, SDL_SysWMinfo * info)
+{
+ Dprintf ("enter NX_GetWMInfo\n") ;
+
+ if (info -> version.major <= SDL_MAJOR_VERSION) {
+ info -> window = SDL_Window ;
+ return 1 ;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION) ;
+ return -1 ;
+ }
+
+ Dprintf ("leave NX_GetWMInfo\n") ;
+}
diff --git a/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm_c.h b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm_c.h
new file mode 100644
index 0000000..77be794
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nanox/SDL_nxwm_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 Sam Lantinga
+ Copyright (C) 2001 Hsieh-Fu Tsai
+
+ 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
+
+ Hsieh-Fu Tsai
+ clare@setabox.com
+*/
+#include "SDL_config.h"
+
+#include "SDL_nxvideo.h"
+
+// Functions to be exported
+extern void NX_SetCaption (_THIS, const char * title, const char * icon) ;
+extern int NX_GetWMInfo (_THIS, SDL_SysWMinfo * info) ;
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents.c b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents.c
new file mode 100644
index 0000000..a4f0fbe
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents.c
@@ -0,0 +1,83 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Being a nds driver, there's no event stream. We just define stubs for
+ most of the API. */
+#include <nds.h>
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ndsvideo.h"
+#include "SDL_ndsevents_c.h"
+
+static SDLKey keymap[NDS_NUMKEYS];
+char keymem[NDS_NUMKEYS]; /* memorize states of buttons */
+
+void NDS_PumpEvents(_THIS)
+{
+ scanKeys();
+ int i;
+ SDL_keysym keysym;
+ keysym.mod=KMOD_NONE;
+ for(i=0;i<NDS_NUMKEYS;i++)
+ {
+ keysym.scancode=i;
+ keysym.sym=keymap[i];
+ if(keysHeld()&(1<<i) && !keymem[i])
+ {
+ keymem[i]=1;
+ //printf("key released %d\n",i);
+ SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+ }
+ if(!(keysHeld()&(1<<i)) && keymem[i])
+ {
+ keymem[i]=0;
+ //printf("key pressed %d\n",i);
+ SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ }
+ //touchPosition touch;
+ //touch=touchReadXY();
+ //if (touch.px!=0 || touch.py!=0)
+ // SDL_PrivateMouseMotion(SDL_PRESSED, 0, touch.px, touch.py);
+}
+
+void NDS_InitOSKeymap(_THIS)
+{
+ SDL_memset(keymem,1,NDS_NUMKEYS);
+ keymap[KEY_A]=SDLK_a;
+ keymap[KEY_B]=SDLK_s;
+ keymap[KEY_X]=SDLK_w;
+ keymap[KEY_Y]=SDLK_d;
+ keymap[KEY_L]=SDLK_q;
+ keymap[KEY_R]=SDLK_e;
+ keymap[KEY_UP]=SDLK_UP;
+ keymap[KEY_DOWN]=SDLK_DOWN;
+ keymap[KEY_LEFT]=SDLK_LEFT;
+ keymap[KEY_RIGHT]=SDLK_RIGHT;
+ keymap[KEY_SELECT]=SDLK_SPACE;
+ keymap[KEY_START]=SDLK_RETURN;
+}
+
+/* end of SDL_gbaevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents_c.h b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents_c.h
new file mode 100644
index 0000000..fcd0ef2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsevents_c.h
@@ -0,0 +1,51 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_ndsvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void NDS_InitOSKeymap(_THIS);
+extern void NDS_PumpEvents(_THIS);
+
+#define NDS_NUMKEYS 12
+
+/*
+#define NDS_JOYPADREG 0x4000130
+#define NDS_JOYPAD (*(volatile Uint16*)NDS_JOYPADREG)
+
+#define NDS_NUMKEYS 10
+#define NDS_KEYA (0)
+#define NDS_KEYB (1)
+#define NDS_KEYSEL (2)
+#define NDS_KEYSTART (3)
+#define NDS_KEYRIGHT (4)
+#define NDS_KEYLEFT (5)
+#define NDS_KEYUP (6)
+#define NDS_KEYDOWN (7)
+#define NDS_KEYR (8)
+#define NDS_KEYL (9)
+*/
+/* end of SDL_NDSevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse.c b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse.c
new file mode 100644
index 0000000..bba1417
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse.c
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_error.h"
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_ndsmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse_c.h b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse_c.h
new file mode 100644
index 0000000..76adf02
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsmouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_ndsvideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.c b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.c
new file mode 100644
index 0000000..d0ee8bf
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.c
@@ -0,0 +1,500 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <nds.h>
+#include <nds/registers_alt.h>
+#include "SDL.h"
+#include "SDL_error.h"
+#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_ndsvideo.h"
+#include "SDL_ndsevents_c.h"
+#include "SDL_ndsmouse_c.h"
+
+#define NDSVID_DRIVER_NAME "nds"
+
+/* Initialization/Query functions */
+static int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void NDS_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int NDS_LockHWSurface(_THIS, SDL_Surface *surface);
+static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* etc. */
+static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+/* NDS driver bootstrap functions */
+
+static int NDS_Available(void)
+{
+ return(1);
+}
+
+static void NDS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+void on_irq_vblank()
+{
+ // Disable interrupts
+ //REG_IME = 0;
+ scanKeys();
+
+ // VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK;
+ // REG_IF |= IRQ_VBLANK;
+ //REG_IF = REG_IF;
+
+ // Enable interrupts
+ //REG_IME = 1;
+}
+
+static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+ {
+ return 0;
+ }
+
+static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ if (src->flags & SDL_SRCALPHA) return false;
+ if (src->flags & SDL_SRCCOLORKEY) return false;
+ if (src->flags & SDL_HWPALETTE ) return false;
+ if (dst->flags & SDL_SRCALPHA) return false;
+ if (dst->flags & SDL_SRCCOLORKEY) return false;
+ if (dst->flags & SDL_HWPALETTE ) return false;
+
+ if (src->format->BitsPerPixel != dst->format->BitsPerPixel) return false;
+ if (src->format->BytesPerPixel != dst->format->BytesPerPixel) return false;
+
+ src->map->hw_blit = HWAccelBlit;
+ return true;
+}
+
+static SDL_VideoDevice *NDS_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device=0;
+
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = NDS_VideoInit;
+ device->ListModes = NDS_ListModes;
+ device->SetVideoMode = NDS_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = NDS_SetColors;
+ device->UpdateRects = NDS_UpdateRects;
+ device->VideoQuit = NDS_VideoQuit;
+ device->AllocHWSurface = NDS_AllocHWSurface;
+ device->CheckHWBlit = CheckHWBlit;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = NDS_LockHWSurface;
+ device->UnlockHWSurface = NDS_UnlockHWSurface;
+ device->FlipHWSurface = NDS_FlipHWSurface;
+ device->FreeHWSurface = NDS_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = NDS_InitOSKeymap;
+ device->PumpEvents = NDS_PumpEvents;
+ device->info.blit_hw=1;
+
+ device->free = NDS_DeleteDevice;
+ return device;
+}
+
+VideoBootStrap NDS_bootstrap = {
+ NDSVID_DRIVER_NAME, "SDL NDS video driver",
+ NDS_Available, NDS_CreateDevice
+};
+
+ u16* frontBuffer;// = (u16*)(0x06000000);
+ u16* backBuffer;// = (u16*)(0x06000000 + 256 * 256 * 2);
+int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ //printf("WARNING: You are using the SDL NDS video driver!\n");
+
+ /* Determine the screen depth (use default 8-bit depth) */
+ /* we change this during the SDL_SetVideoMode implementation... */
+ vformat->BitsPerPixel = 16; // mode 3
+ vformat->BytesPerPixel = 2;
+ vformat->Rmask = 0x0000f800;
+ vformat->Gmask = 0x000007e0;
+ vformat->Bmask = 0x0000001f;
+ powerON(POWER_ALL);
+ irqInit();
+ irqSet(IRQ_VBLANK, on_irq_vblank);
+ irqEnable(IRQ_VBLANK);
+
+ //set the mode for 2 text layers and two extended background layers
+ //videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
+ videoSetMode(MODE_6_2D| DISPLAY_BG2_ACTIVE);
+
+ //set the sub background up for text display (we could just print to one
+ //of the main display text backgrounds just as easily
+ videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
+
+ //set the first two banks as background memory and the third as sub background memory
+ //D is not used..if you need a bigger background then you will need to map
+ //more vram banks consecutivly (VRAM A-D are all 0x20000 bytes in size)
+ //vramSetMainBanks(VRAM_A_MAIN_BG_0x6000000, VRAM_B_MAIN_BG_0x6020000,VRAM_C_SUB_BG , VRAM_D_LCD);
+ vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG);
+ //vramSetBankA(VRAM_A_MAIN_BG);
+ //vramSetBankB(VRAM_B_MAIN_BG);
+ //vramSetBankC(VRAM_C_MAIN_BG);
+ //vramSetBankD(VRAM_D_MAIN_BG);
+ //vramSetBankE(VRAM_E_MAIN_BG);
+ //vramSetBankF(VRAM_F_MAIN_BG);
+ //vramSetBankG(VRAM_G_MAIN_BG);
+ vramSetBankH(VRAM_H_SUB_BG);
+ vramSetBankI(VRAM_I_LCD);
+
+ ////////////////set up text background for text/////////////////////
+ SUB_BG0_CR = BG_MAP_BASE(8);
+
+ BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
+ ///////////////set up our bitmap background///////////////////////
+
+ //BG3_CR = BG_BMP16_512x512;
+
+ //these are rotation backgrounds so you must set the rotation attributes:
+ //these are fixed point numbers with the low 8 bits the fractional part
+ //this basicaly gives it a 1:1 translation in x and y so you get a nice flat bitmap
+ /* BG3_XDX = 1<<8;
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = 1<<8;
+ //our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2
+ BG3_CX = 0;
+ BG3_CY = 0;
+ */
+ //consoleInit() is a lot more flexible but this gets you up and running quick
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(8), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
+
+
+ frontBuffer =(u16*)(0x06000000);
+ //backBuffer =(u16*)(0x06000000 + 1024 * 512*2);
+
+ //lcdSwap();
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return (SDL_Rect **) -1;
+}
+
+SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Uint32 Rmask, Gmask, Bmask, Amask;
+
+ //if(width > 1024 || height > 512 || bpp > 16)
+ // return(NULL);
+
+ if(bpp >8) {
+ bpp=16;
+ Rmask = 0x0000001F;
+ Gmask = 0x000003E0;
+ Bmask = 0x00007C00;
+ Amask = 0x00008000;
+
+ videoSetMode(MODE_5_2D| DISPLAY_BG2_ACTIVE);
+
+ vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG);
+
+ BG2_CR = BG_BMP16_512x512;
+ BG2_XDX = ((width / 256) << 8) | (width % 256) ;
+ BG2_XDY = 0;
+ BG2_YDX = 0;
+ BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ;
+ BG2_CX = 0;
+ BG2_CY = 0;
+// for (i=0;i<256*192;i++)
+// frontBuffer[i] = RGB15(31,0,0)|BIT(15);
+ }
+ else
+ if(bpp <= 8) {
+ bpp=8;
+ Rmask = 0x00000000;
+ Gmask = 0x00000000;
+ Bmask = 0x00000000;
+ BG2_CR = BG_BMP8_1024x512;
+ BG2_XDX = ((width / 256) << 8) | (width % 256) ;
+ BG2_XDY = 0;
+ BG2_YDX = 0;
+ BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ;
+
+ }
+ else
+ if(bpp < 15) bpp=15;
+ if(width<=256) width=256;
+ else
+ if(width<256) width=256;
+ if(height<=192) height=192;
+ else
+ if(height<192) height=192;
+
+ if(bpp==8)
+ {
+ if(width<256) width=256;
+ if(height<192) height=192;
+ this->hidden->ndsmode=4;
+ }
+
+ if(bpp==15)
+ {
+ if(width<256) this->hidden->ndsmode=5;
+ else this->hidden->ndsmode=3;
+ }
+
+ this->hidden->buffer= frontBuffer;//NDS_VRAM_BASE;
+
+ //NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2;
+
+ //fprintf(stderr,"Setting mode %dx%d (ndsmode %d)\n", width, height,this->hidden->ndsmode);
+
+ // FIXME: How do I tell that 15 bits mode is 555?
+
+ SDL_memset(this->hidden->buffer, 0, 1024 * 512* ((this->hidden->ndsmode==4 || this->hidden->ndsmode==5) ? 2 : 1 ) * ((bpp+7) / 8));
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, Amask) ) {
+ this->hidden->buffer = NULL;
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | (this->hidden->ndsmode > 0 ? SDL_DOUBLEBUF : 0);
+ this->hidden->w = current->w = width;
+ this->hidden->h = current->h = height;
+ current->pixels = frontBuffer;
+
+ if (flags & SDL_DOUBLEBUF) {
+ this->hidden->secondbufferallocd=1;
+ backBuffer=(u16*)SDL_malloc(1024*512*2);
+ current->pixels = backBuffer;
+ }
+ if(bpp==8)
+ current->pitch =1024;
+ else
+ current->pitch =512*2;
+
+ /* We're done */
+ return(current);
+}
+
+static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ if(this->hidden->secondbufferallocd) {
+ //printf("double double buffer alloc\n");
+ return -1;
+ }
+ //if(this->hidden->ndsmode==3)
+ //{
+ // printf("no 2nd buffer in mode3\n");
+ // return -1;
+ //}
+ //printf("second buffer\n");
+ //this->hidden->secondbufferallocd=1;
+ //backBuffer=(u16*)malloc(1024*512*2);
+ //surface->pixels = backBuffer;
+
+ return(0);
+}
+static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ //free(backBuffer);
+ this->hidden->secondbufferallocd=0;
+}
+int z=0;
+/* We need to wait for vertical retrace on page flipped displays */
+static int NDS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+/*
+ uint8* a = surface->pixels;
+ int i,j;
+ a += 5 * SCREEN_WIDTH + 5;
+ for( i = 0; i < 195; ++i) {
+ uint16* line = a + (SCREEN_WIDTH * i);
+ for( j = 0; j < 158; ++j) {
+ *line++ = RGB15(155,155,25);
+ }
+ }
+*/
+ //if (z <256)
+ // BG_PALETTE[z++]=RGB15(255-z,z,255-z);
+
+
+ return(0);
+}
+
+static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if(this->hidden->secondbufferallocd){
+ while(DISP_Y!=192);
+ while(DISP_Y==192);
+ //printf("flip");
+
+ dmaCopyAsynch(backBuffer,frontBuffer,1024*512);
+ }
+ //printf("flip\n");
+ //u16* temp = surface->pixels;
+ //surface->pixels = frontBuffer;
+ //frontBuffer = temp;
+ /* u8* vram=BG_GFX;
+ int x,y;
+ for(y = 0; y < 512; y++)
+ dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512);
+ //unsigned char buf;
+
+ //printf("NDS_FlipHWSurface\n");
+ //printf("ptr now: 0x%x\n",surface->pixels);
+
+ while(DISP_Y!=192);
+ while(DISP_Y==192);
+ //swap
+ u16* temp = frontBuffer;
+ frontBuffer = backBuffer;
+ backBuffer = temp;
+
+ //flip
+ //base is 16KB and screen size is 256x256x2 (128KB)
+ BG2_CR ^= BG_BMP_BASE( 512 / 16 ); */
+/*
+ if(surface->pixels == frontBuffer)//NDS_VRAM_BASE)
+ {
+ while(DISP_Y!=192);
+ while(DISP_Y==192);
+ //swap
+ u16* temp = backBuffer;
+ backBuffer = frontBuffer;
+ frontBuffer = temp;
+
+ //flip
+ //base is 16KB and screen size is 256x256x2 (128KB)
+ BG3_CR ^= BG_BMP_BASE( 128 / 16 );
+ }
+ else
+ {
+
+ while(DISP_Y!=192);
+ while(DISP_Y==192);
+ //swap
+ u16* temp = frontBuffer;
+ frontBuffer = backBuffer;
+ backBuffer = temp;
+
+ //flip
+ //base is 16KB and screen size is 256x256x2 (128KB)
+ BG3_CR ^= BG_BMP_BASE( 128 / 16 );
+
+ }
+ */
+ //printf("ptr then: 0x%x\n",surface->pixels);
+
+ //printf("setting dispcnt to 0x%x\n",NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2| buf);
+ return(0);
+}
+
+static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ //fprintf(stderr,"update\n");
+ /* do nothing. */
+ //dmaCopy(frontBuffer,BG_GFX,512*512);
+ /*
+ u8* vram=(u8*)BG_GFX;
+ int x,y;
+ for(y = 0; y < 512; y++)
+ dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512);
+ */
+
+}
+
+int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ //printf("SetColors\n");
+ short r,g,b;
+
+ if(this->hidden->ndsmode != 4)
+ {
+ printf("This is not a palettized mode\n");
+ return -1;
+ }
+
+ int i,j=firstcolor+ncolors;
+ for(i=firstcolor;i<j;i++)
+ {
+ r=colors[i].r>>3;
+ g=colors[i].g>>3;
+ b=colors[i].b>>3;
+ BG_PALETTE[i]=RGB15(r, g, b);
+ }
+
+ return(0);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void NDS_VideoQuit(_THIS)
+{
+}
diff --git a/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.h b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.h
new file mode 100644
index 0000000..015f655
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/nds/SDL_ndsvideo.h
@@ -0,0 +1,61 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_ndsvideo_h
+#define _SDL_ndsvideo_h
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ int w, h;
+ void *buffer;
+ short ndsmode;
+ short secondbufferallocd;
+};
+
+/*
+#define NDS_VIDC_BASE 0x4000000
+#define NDS_DISPCNT (*(volatile Uint32*)(NDS_VIDC_BASE))
+#define NDS_VIDC_SCANLINE (NDS_VIDC_BASE+6)
+#define NDS_SCANLINE (*(volatile Uint8*)(NDS_VIDC_SCANLINE))
+
+#define NDS_DISP_MODE(n) (n&7)
+#define NDS_DISP_BG2 0x400
+#define NDS_DISP_FB 0x10
+
+#define NDS_PAL_BASE 0x5000000
+#define NDS_BGPAL ((volatile Uint16*)(NDS_PAL_BASE))
+#define NDS_OBJPAL ((volatile Uint16*)(NDS_PAL_BASE+0x200))
+
+#define NDS_VRAM_BASE 0x6000000
+#define NDS_VRAM_2NDBUF 0x600a000
+#define NDS_VRAM = ((volatile Uint16* )NDS_VRAM_BASE)
+*/
+#endif /* _SDL_ndsvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.c b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.c
new file mode 100644
index 0000000..a902d1f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.c
@@ -0,0 +1,3018 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 <unidef.h> // Unicode API
+#include <uconv.h> // Unicode API (codepage conversion)
+
+#include <process.h>
+#include <time.h>
+
+#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
+};
+
diff --git a/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.h b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.h
new file mode 100644
index 0000000..6d58baf
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_os2fslib.h
@@ -0,0 +1,71 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 <os2.h>
+
+#include <FSLib.h>
+
+/* 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 */
diff --git a/distrib/sdl-1.2.15/src/video/os2fslib/SDL_vkeys.h b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_vkeys.h
new file mode 100644
index 0000000..79380d5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/os2fslib/SDL_vkeys.h
@@ -0,0 +1,74 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events.c
new file mode 100644
index 0000000..9b7538c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events.c
@@ -0,0 +1,624 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting photon events into SDL events */
+
+#include <stdio.h>
+#include <setjmp.h>
+#include <sys/time.h>
+
+#include <Ph.h>
+#include <photon/PkKeyDef.h>
+
+#include "SDL.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ph_video.h"
+#include "SDL_ph_modes_c.h"
+#include "SDL_ph_image_c.h"
+#include "SDL_ph_events_c.h"
+#include "SDL_phyuv_c.h"
+
+/* The translation tables from a photon keysym to a SDL keysym */
+static SDLKey ODD_keymap[256];
+static SDLKey MISC_keymap[0xFF + 1];
+SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
+
+/* Check to see if this is a repeated key.
+ (idea shamelessly lifted from GII -- thanks guys! :) */
+static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
+{
+ PhRect_t *rect = PhGetRects( winEvent );
+
+ int centre_x, centre_y;
+ int dx, dy;
+ short abs_x, abs_y;
+ int posted;
+
+ centre_x = SDL_VideoSurface->w / 2;
+ centre_y = SDL_VideoSurface->h / 2;
+
+ dx = rect->ul.x - centre_x;
+ dy = rect->ul.y - centre_y;
+
+ posted = SDL_PrivateMouseMotion( 0, 1, dx, dy );
+
+ /* Move mouse cursor to middle of the window */
+ PtGetAbsPosition( window, &abs_x, &abs_y );
+ PhMoveCursorAbs(PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y);
+
+ return (posted);
+}
+
+/* Control which motion flags the window has set, a flags value of -1 sets
+ * MOTION_BUTTON and MOTION_NOBUTTON */
+
+static void set_motion_sensitivity(_THIS, unsigned int flags)
+{
+ int rid;
+ int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
+ PhRegion_t region;
+
+ if( window )
+ {
+ rid = PtWidgetRid(window);
+ if( rid != 0 && PhRegionQuery(rid, &region, NULL, NULL, 0) == 0 )
+ {
+ region.events_sense=(region.events_sense & ~fields)|(flags & fields);
+ PhRegionChange(Ph_REGION_EV_SENSE, 0, &region, NULL, NULL);
+ }
+ }
+}
+
+/* Convert the photon button state value to an SDL value */
+static Uint8 ph2sdl_mousebutton(unsigned short button_state)
+{
+ Uint8 mouse_button = 0;
+
+ if (button_state & Ph_BUTTON_SELECT)
+ mouse_button |= SDL_BUTTON_LEFT;
+ if (button_state & Ph_BUTTON_MENU)
+ mouse_button |= SDL_BUTTON_RIGHT;
+ if (button_state & Ph_BUTTON_ADJUST)
+ mouse_button |= SDL_BUTTON_MIDDLE;
+
+ return (mouse_button);
+}
+
+static int ph_DispatchEvent(_THIS)
+{
+ int posted;
+ PhRect_t* rect;
+ PhPointerEvent_t* pointerEvent;
+ PhKeyEvent_t* keyEvent;
+ PhWindowEvent_t* winEvent;
+ int i, buttons;
+ SDL_Rect sdlrects[PH_SDL_MAX_RECTS];
+
+ posted = 0;
+
+ switch (phevent->type)
+ {
+ case Ph_EV_BOUNDARY:
+ {
+ if (phevent->subtype == Ph_EV_PTR_ENTER)
+ {
+ posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ }
+ else if (phevent->subtype ==Ph_EV_PTR_LEAVE)
+ {
+ posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+ }
+ break;
+
+ case Ph_EV_PTR_MOTION_BUTTON:
+ case Ph_EV_PTR_MOTION_NOBUTTON:
+ {
+ if (SDL_VideoSurface)
+ {
+ pointerEvent = PhGetData(phevent);
+ rect = PhGetRects(phevent);
+
+ if (mouse_relative)
+ {
+ posted = ph_WarpedMotion(this, phevent);
+ }
+ else
+ {
+ posted = SDL_PrivateMouseMotion(0, 0, rect->ul.x, rect->ul.y);
+ }
+ }
+ }
+ break;
+
+ case Ph_EV_BUT_PRESS:
+ {
+ pointerEvent = PhGetData(phevent);
+ buttons = ph2sdl_mousebutton(pointerEvent->buttons);
+ if (buttons != 0)
+ {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED, buttons, 0, 0);
+ }
+ }
+ break;
+
+ case Ph_EV_BUT_RELEASE:
+ {
+ pointerEvent = PhGetData(phevent);
+ buttons = ph2sdl_mousebutton(pointerEvent->buttons);
+ if (phevent->subtype == Ph_EV_RELEASE_REAL && buttons != 0)
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
+ }
+ else if(phevent->subtype == Ph_EV_RELEASE_PHANTOM)
+ {
+ /* If the mouse is outside the window,
+ * only a phantom release event is sent, so
+ * check if the window doesn't have mouse focus.
+ * Not perfect, maybe checking the mouse button
+ * state for Ph_EV_BOUNDARY events would be
+ * better. */
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0)
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
+ }
+ }
+ }
+ break;
+
+ case Ph_EV_WM:
+ {
+ winEvent = PhGetData(phevent);
+
+ /* losing focus */
+ if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST))
+ {
+ set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON);
+ posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+ }
+ /* gaining focus */
+ else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS))
+ {
+ set_motion_sensitivity(this, -1);
+ posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+ }
+ /* request quit */
+ else if (winEvent->event_f==Ph_WM_CLOSE)
+ {
+ posted = SDL_PrivateQuit();
+ }
+ /* request hide/unhide */
+ else if (winEvent->event_f==Ph_WM_HIDE)
+ {
+ if (currently_hided)
+ {
+ /* got unhide window event */
+ /* TODO: restore application's palette if in palette mode */
+ currently_hided=0;
+ }
+ else
+ {
+ /* got hide window event */
+ /* TODO: restore original palette if in palette mode */
+ currently_hided=1;
+ }
+ }
+ /* request to resize */
+ else if (winEvent->event_f==Ph_WM_RESIZE)
+ {
+ currently_maximized=0;
+ #if (_NTO_VERSION < 630)
+ SDL_PrivateResize(winEvent->size.w+1, winEvent->size.h+1);
+ #else
+ /* QNX 6.3.0 have this bug fixed */
+ SDL_PrivateResize(winEvent->size.w, winEvent->size.h);
+ #endif /* _NTO_VERSION */
+ }
+ /* request to move */
+ else if (winEvent->event_f==Ph_WM_MOVE)
+ {
+ if (current_overlay!=NULL)
+ {
+ int lockedstate=current_overlay->hwdata->locked;
+ int chromastate=current_overlay->hwdata->ischromakey;
+ int error;
+ SDL_Rect src, dst;
+
+ current_overlay->hwdata->locked=1;
+ src.x = 0;
+ src.y = 0;
+ src.w = current_overlay->w;
+ src.y = current_overlay->h;
+ dst.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+ dst.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+ dst.w=current_overlay->hwdata->CurrentViewPort.size.w;
+ dst.h=current_overlay->hwdata->CurrentViewPort.size.h;
+ current_overlay->hwdata->ischromakey=0;
+ error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst);
+ if (!error)
+ {
+ current_overlay->hwdata->ischromakey=chromastate;
+ current_overlay->hwdata->locked=lockedstate;
+ }
+ }
+ }
+ /* maximize request */
+ else if (winEvent->event_f==Ph_WM_MAX)
+ {
+ /* window already moved and resized here */
+ currently_maximized=1;
+ }
+ /* restore request */
+ else if (winEvent->event_f==Ph_WM_RESTORE)
+ {
+ /* window already moved and resized here */
+ currently_maximized=0;
+ }
+ }
+ break;
+
+ /* window has been resized, moved or removed */
+ case Ph_EV_EXPOSE:
+ {
+ if (phevent->num_rects!=0)
+ {
+ int numrects;
+
+ if (SDL_VideoSurface)
+ {
+ rect = PhGetRects(phevent);
+ if (phevent->num_rects>PH_SDL_MAX_RECTS)
+ {
+ /* sorry, buffers underrun, we'll update only first PH_SDL_MAX_RECTS rects */
+ numrects=PH_SDL_MAX_RECTS;
+ }
+
+ for(i=0; i<phevent->num_rects; i++)
+ {
+ sdlrects[i].x = rect[i].ul.x;
+ sdlrects[i].y = rect[i].ul.y;
+ sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
+ sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
+ }
+
+ this->UpdateRects(this, phevent->num_rects, sdlrects);
+
+ if (current_overlay!=NULL)
+ {
+ int lockedstate=current_overlay->hwdata->locked;
+ int error;
+ SDL_Rect src, dst;
+
+ current_overlay->hwdata->locked=1;
+ src.x = 0;
+ src.y = 0;
+ src.w = current_overlay->w;
+ src.y = current_overlay->h;
+ dst.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+ dst.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+ dst.w=current_overlay->hwdata->CurrentViewPort.size.w;
+ dst.h=current_overlay->hwdata->CurrentViewPort.size.h;
+ current_overlay->hwdata->forcedredraw=1;
+ error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst);
+ if (!error)
+ {
+ current_overlay->hwdata->forcedredraw=0;
+ current_overlay->hwdata->locked=lockedstate;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case Ph_EV_KEY:
+ {
+ SDL_keysym keysym;
+
+ posted = 0;
+
+ keyEvent = PhGetData(phevent);
+
+ if (Pk_KF_Key_Down & keyEvent->key_flags)
+ {
+ /* split the wheel events from real key events */
+ if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
+ break;
+ }
+ if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ break;
+ }
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym));
+ }
+ else /* must be key release */
+ {
+ /* split the wheel events from real key events */
+ if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
+ break;
+ }
+ if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+ {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
+ break;
+ }
+ posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym));
+ }
+ }
+ break;
+
+ case Ph_EV_INFO:
+ {
+ if (phevent->subtype==Ph_OFFSCREEN_INVALID)
+ {
+ unsigned long* EvInfoData;
+
+ EvInfoData=(unsigned long*)PhGetData(phevent);
+
+ switch (*EvInfoData)
+ {
+ case Pg_VIDEO_MODE_SWITCHED:
+ {
+ }
+ break;
+ case Pg_ENTERED_DIRECT:
+ {
+ }
+ break;
+ case Pg_EXITED_DIRECT:
+ {
+ }
+ break;
+ case Pg_DRIVER_STARTED:
+ {
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ return(posted);
+}
+
+/* perform a blocking read if no events available */
+int ph_Pending(_THIS)
+{
+ /* Flush the display connection and look to see if events are queued */
+ PgFlush();
+
+ while (1)
+ {
+ switch(PhEventPeek(phevent, EVENT_SIZE))
+ {
+ case Ph_EVENT_MSG:
+ return 1;
+ case -1:
+ SDL_SetError("ph_Pending(): PhEventNext failed.\n");
+ return 0;
+ default:
+ return 0;
+ }
+ }
+
+ /* Oh well, nothing is ready .. */
+ return(0);
+}
+
+void ph_PumpEvents(_THIS)
+{
+ /* Flush the display connection and look to see if events are queued */
+ PgFlush();
+
+ while (ph_Pending(this))
+ {
+ PtEventHandler(phevent);
+ ph_DispatchEvent(this);
+ }
+}
+
+void ph_InitKeymap(void)
+{
+ int i;
+
+ /* Odd keys used in international keyboards */
+ for (i=0; i<SDL_arraysize(ODD_keymap); ++i)
+ {
+ ODD_keymap[i] = SDLK_UNKNOWN;
+ }
+
+ /* Map the miscellaneous keys */
+ for (i=0; i<SDL_arraysize(MISC_keymap); ++i)
+ {
+ MISC_keymap[i] = SDLK_UNKNOWN;
+ }
+
+ MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
+ MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
+ MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
+ MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
+ MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
+ MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
+ MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
+
+ MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
+ MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
+ MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
+ MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
+ MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
+ MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
+ MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
+ MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
+ MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
+ MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
+
+ MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
+ MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
+ MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
+ MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
+ MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
+ MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
+ MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
+
+ MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
+ MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
+ MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
+ MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
+ MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
+ MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
+ MISC_keymap[Pk_End&0xFF] = SDLK_END;
+ MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
+ MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
+
+ MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
+ MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
+ MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
+ MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
+ MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
+ MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
+ MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
+ MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
+ MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
+ MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
+ MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
+ MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
+ MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
+ MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
+ MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
+
+ MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
+ MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
+ MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
+ MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
+ MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
+ MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
+ MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
+ MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
+ MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
+ MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
+ MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
+ MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER;
+ MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER;
+ MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */
+
+ MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
+ MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
+ MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
+ MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU; /* Windows "Menu" key */
+
+ MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER; /* Right "Windows" */
+
+ /* Left "Windows" key, but it can't be catched by application */
+ MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER;
+}
+
+static unsigned long cap;
+
+SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
+{
+ /* 'sym' is set to the value of the key with modifiers applied to it.
+ This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
+ We will assume it is valid. */
+
+ /* FIXME: This needs to check whether the cap & scancode is valid */
+
+ cap = key->key_cap;
+
+ switch (cap>>8)
+ {
+ case 0x00: /* Latin 1 */
+ case 0x01: /* Latin 2 */
+ case 0x02: /* Latin 3 */
+ case 0x03: /* Latin 4 */
+ case 0x04: /* Katakana */
+ case 0x05: /* Arabic */
+ case 0x06: /* Cyrillic */
+ case 0x07: /* Greek */
+ case 0x08: /* Technical */
+ case 0x0A: /* Publishing */
+ case 0x0C: /* Hebrew */
+ case 0x0D: /* Thai */
+ keysym->sym = (SDLKey)(cap&0xFF);
+ /* Map capital letter syms to lowercase */
+ if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
+ keysym->sym += ('a'-'A');
+ break;
+ case 0xF0:
+ keysym->sym = MISC_keymap[cap&0xFF];
+ break;
+ default:
+ keysym->sym = SDLK_UNKNOWN;
+ break;
+ }
+
+ keysym->scancode = key->key_scan;
+ keysym->unicode = 0;
+
+ if (SDL_TranslateUNICODE)
+ {
+ char utf8[MB_CUR_MAX];
+ int utf8len;
+ wchar_t unicode;
+
+ switch (keysym->scancode)
+ {
+ /* Esc key */
+ case 0x01: keysym->unicode = 27;
+ break;
+ /* BackSpace key */
+ case 0x0E: keysym->unicode = 127;
+ break;
+ /* Enter key */
+ case 0x1C: keysym->unicode = 10;
+ break;
+ default:
+ utf8len = PhKeyToMb(utf8, key);
+ if (utf8len > 0)
+ {
+ utf8len = mbtowc(&unicode, utf8, utf8len);
+ if (utf8len > 0)
+ {
+ keysym->unicode = unicode;
+ }
+ }
+ break;
+ }
+
+ }
+
+ return (keysym);
+}
+
+void ph_InitOSKeymap(_THIS)
+{
+ ph_InitKeymap();
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events_c.h
new file mode 100644
index 0000000..4aa939b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_events_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_EVENTS_H__
+#define __SDL_PH_EVENTS_H__
+
+#include "SDL_ph_video.h"
+
+#define PH_SDL_MAX_RECTS 256
+#define PH_EVENT_SAFETY_POOL 512
+#define EVENT_SIZE (sizeof(PhEvent_t) + 1000 + PH_EVENT_SAFETY_POOL)
+
+/* Functions to be exported */
+extern void ph_InitOSKeymap(_THIS);
+extern void ph_PumpEvents(_THIS);
+
+#endif /* __SDL_PH_EVENTS_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.c
new file mode 100644
index 0000000..3121777
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.c
@@ -0,0 +1,406 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <dlfcn.h>
+#include "SDL.h"
+#include "SDL_ph_gl.h"
+
+#if SDL_VIDEO_OPENGL
+
+#if (_NTO_VERSION >= 630)
+ /* PhotonGL functions */
+ GLPH_DECLARE_FUNCS;
+#endif /* 6.3.0 */
+
+#if (_NTO_VERSION < 630)
+void ph_GL_SwapBuffers(_THIS)
+{
+ PgSetRegion(PtWidgetRid(window));
+ PdOpenGLContextSwapBuffers(oglctx);
+}
+#else
+void ph_GL_SwapBuffers(_THIS)
+{
+ qnxgl_swap_buffers(oglbuffers);
+}
+#endif /* 6.3.0 */
+
+int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ switch (attrib)
+ {
+ case SDL_GL_DOUBLEBUFFER:
+ *value=this->gl_config.double_buffer;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ *value=this->gl_config.stencil_size;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ *value=this->gl_config.depth_size;
+ break;
+#if (_NTO_VERSION >= 630)
+ case SDL_GL_RED_SIZE:
+ *value=this->gl_config.red_size;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ *value=this->gl_config.green_size;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ *value=this->gl_config.blue_size;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ *value=this->gl_config.alpha_size;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ *value=this->gl_config.accum_red_size;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ *value=this->gl_config.accum_green_size;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ *value=this->gl_config.accum_blue_size;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ *value=this->gl_config.accum_alpha_size;
+ break;
+ case SDL_GL_STEREO:
+ *value=this->gl_config.stereo;
+ break;
+#endif /* 6.3.0 */
+ default:
+ *value=0;
+ return(-1);
+ }
+ return 0;
+}
+
+#if (_NTO_VERSION < 630)
+int ph_GL_LoadLibrary(_THIS, const char* path)
+{
+ /* if code compiled with SDL_VIDEO_OPENGL, that mean that library already linked */
+ this->gl_config.driver_loaded = 1;
+
+ return 0;
+}
+#else
+int ph_GL_LoadLibrary(_THIS, const char* path)
+{
+ void* handle;
+ int dlopen_flags=RTLD_WORLD | RTLD_GROUP;
+
+ if (this->gl_config.dll_handle!=NULL)
+ {
+ return 0;
+ }
+
+ handle = dlopen(path, dlopen_flags);
+
+ if (handle==NULL)
+ {
+ SDL_SetError("ph_GL_LoadLibrary(): Could not load OpenGL library");
+ return -1;
+ }
+
+ this->gl_config.dll_handle = handle;
+ this->gl_config.driver_loaded = 1;
+
+ SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path));
+
+ return 0;
+}
+#endif /* 6.3.0 */
+
+#if (_NTO_VERSION < 630)
+void* ph_GL_GetProcAddress(_THIS, const char* proc)
+{
+ return NULL;
+}
+#else
+void* ph_GL_GetProcAddress(_THIS, const char* proc)
+{
+ void* function;
+
+ if (this->gl_config.dll_handle==NULL)
+ {
+ ph_GL_LoadLibrary(this, DEFAULT_OPENGL);
+ if (this->gl_config.dll_handle==NULL)
+ {
+ return NULL;
+ }
+ }
+
+ function=qnxgl_get_func(proc, oglctx, 0);
+ if (function==NULL)
+ {
+ function=dlsym(this->gl_config.dll_handle, proc);
+ }
+
+ return function;
+}
+#endif /* 6.3.0 */
+
+#if (_NTO_VERSION < 630)
+int ph_GL_MakeCurrent(_THIS)
+{
+ PgSetRegion(PtWidgetRid(window));
+
+ if (oglctx!=NULL)
+ {
+ PhDCSetCurrent(oglctx);
+ }
+
+ return 0;
+}
+#else
+int ph_GL_MakeCurrent(_THIS)
+{
+ PgSetRegion(PtWidgetRid(window));
+
+ if (oglctx!=NULL)
+ {
+ if (qnxgl_set_current(oglctx) == -1)
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#endif /* 6.3.0 */
+
+#if (_NTO_VERSION < 630)
+
+/* This code is actual for the Photon3D Runtime which was available prior to 6.3 only */
+
+int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
+{
+ PhDim_t dim;
+ uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS];
+ int exposepost=0;
+ int OGLargc;
+
+ dim.w=width;
+ dim.h=height;
+
+ if ((oglctx!=NULL) && (oglflags==flags) && (oglbpp==bpp))
+ {
+ PdOpenGLContextResize(oglctx, &dim);
+ PhDCSetCurrent(oglctx);
+ return 0;
+ }
+ else
+ {
+ if (oglctx!=NULL)
+ {
+ PhDCSetCurrent(NULL);
+ PhDCRelease(oglctx);
+ oglctx=NULL;
+ exposepost=1;
+ }
+ }
+
+ OGLargc=0;
+ if (this->gl_config.depth_size)
+ {
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DEPTH_BITS;
+ OGLAttrib[OGLargc++]=this->gl_config.depth_size;
+ }
+ if (this->gl_config.stencil_size)
+ {
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_STENCIL_BITS;
+ OGLAttrib[OGLargc++]=this->gl_config.stencil_size;
+ }
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW;
+ if (flags & SDL_FULLSCREEN)
+ {
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN;
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DIRECT;
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_BEST;
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_CENTER;
+ }
+ OGLAttrib[OGLargc++]=PHOGL_ATTRIB_NONE;
+
+ if (this->gl_config.double_buffer)
+ {
+ oglctx=PdCreateOpenGLContext(2, &dim, 0, OGLAttrib);
+ }
+ else
+ {
+ oglctx=PdCreateOpenGLContext(1, &dim, 0, OGLAttrib);
+ }
+
+ if (oglctx==NULL)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): cannot create OpenGL context !\n");
+ return -1;
+ }
+
+ PhDCSetCurrent(oglctx);
+
+ PtFlush();
+
+ oglflags=flags;
+ oglbpp=bpp;
+
+ if (exposepost!=0)
+ {
+ /* OpenGL context has been recreated, so report about this fact */
+ SDL_PrivateExpose();
+ }
+
+ return 0;
+}
+
+#else /* _NTO_VERSION */
+
+/* This code is actual for the built-in PhGL support, which became available since 6.3 */
+
+int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
+{
+ qnxgl_buf_attrib_t qnxgl_attribs[PH_OGL_MAX_ATTRIBS];
+ qnxgl_buf_attrib_t* qnxgl_attribs_slide;
+ int num_interfaces = 0;
+ int num_buffers = 0;
+
+ /* Initialize the OpenGL subsystem */
+
+ num_interfaces = qnxgl_init(NULL, NULL, 0);
+
+ if (num_interfaces < 0)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): cannot initialize OpenGL subsystem !\n");
+ return -1;
+ }
+ if (num_interfaces == 0)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): there are no available OpenGL renderers was found !\n");
+ return -1;
+ }
+
+ /* Driver is linked */
+ this->gl_config.driver_loaded=1;
+
+ /* Initialize the OpenGL context attributes */
+ qnxgl_attribs_slide=qnxgl_attribs;
+
+ /* Depth size */
+ if (this->gl_config.depth_size)
+ {
+ fprintf(stderr, "setted depth size %d\n", this->gl_config.depth_size);
+ qnxgl_attribs_slide = qnxgl_attrib_set_depth(qnxgl_attribs_slide, this->gl_config.depth_size);
+ }
+
+ /* Stencil size */
+ if (this->gl_config.stencil_size)
+ {
+ qnxgl_attribs_slide = qnxgl_attrib_set_stencil(qnxgl_attribs_slide, this->gl_config.stencil_size);
+ }
+
+ /* The sum of the accum bits of each channel */
+ if ((this->gl_config.accum_red_size != 0) && (this->gl_config.accum_blue_size != 0) &&
+ (this->gl_config.accum_green_size != 0))
+ {
+ qnxgl_attribs_slide = qnxgl_attrib_set_accum(qnxgl_attribs_slide,
+ this->gl_config.accum_red_size + this->gl_config.accum_blue_size +
+ this->gl_config.accum_green_size + this->gl_config.accum_alpha_size);
+ }
+
+ /* Stereo mode */
+ if (this->gl_config.stereo)
+ {
+ qnxgl_attribs_slide = qnxgl_attrib_set_stereo(qnxgl_attribs_slide);
+ }
+
+ /* Fullscreen mode */
+ if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ qnxgl_attribs_slide = qnxgl_attrib_set_hint_fullscreen(qnxgl_attribs_slide);
+ }
+
+ /* Double buffering mode */
+ if (this->gl_config.double_buffer)
+ {
+ num_buffers=2;
+ }
+ else
+ {
+ num_buffers=1;
+ }
+
+ /* Loading the function pointers so we can use the extensions */
+ GLPH_LOAD_FUNCS_GC(oglctx);
+
+ /* Set the buffers region to be that of our window's region */
+ qnxgl_attribs_slide = glph_attrib_set_region(qnxgl_attribs_slide, PtWidgetRid(window));
+
+ /* End of the attributes array */
+ qnxgl_attribs_slide = qnxgl_attrib_set_end(qnxgl_attribs_slide);
+
+ /* Create the buffers with the specified color model */
+ fprintf(stderr, "ARGB: %d, %d, %d, %d\n", this->gl_config.alpha_size, this->gl_config.red_size, this->gl_config.green_size, this->gl_config.blue_size);
+ oglbuffers = qnxgl_buffers_create(
+ QNXGL_FORMAT_BEST_RGB,
+/* __QNXGL_BUILD_FORMAT(0, __QNXGL_COLOR_MODEL_RGB, this->gl_config.alpha_size,
+ this->gl_config.red_size, this->gl_config.green_size, this->gl_config.blue_size), */
+ num_buffers, width, height, qnxgl_attribs, -1);
+
+
+ if (oglbuffers == NULL)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): failed to create OpenGL buffers !\n");
+ qnxgl_finish();
+ return -1;
+ }
+
+ /* Create a QNXGL context for the previously created buffer */
+ oglctx = qnxgl_context_create(oglbuffers, NULL);
+
+ if (oglctx == NULL)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): failed to create OpenGL context !\n");
+ qnxgl_buffers_destroy(oglbuffers);
+ qnxgl_finish();
+ return -1;
+ }
+
+ /* Attempt to make the context current so we can use OpenGL commands */
+ if (qnxgl_set_current(oglctx) == -1)
+ {
+ SDL_SetError("ph_SetupOpenGLContext(): failed to make the OpenGL context current !\n");
+ qnxgl_context_destroy(oglctx);
+ qnxgl_buffers_destroy(oglbuffers);
+ qnxgl_finish();
+ return -1;
+ }
+
+ PtFlush();
+
+ oglflags=flags;
+ oglbpp=bpp;
+
+ return 0;
+}
+
+#endif /* _NTO_VERSION */
+
+#endif /* SDL_VIDEO_OPENGL */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.h
new file mode 100644
index 0000000..1fb134a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_gl.h
@@ -0,0 +1,41 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_GL_H__
+#define __SDL_PH_GL_H__
+
+#include "SDL_ph_video.h"
+
+#define DEFAULT_OPENGL "/usr/lib/libGL.so"
+
+#if SDL_VIDEO_OPENGL
+ void ph_GL_SwapBuffers(_THIS);
+ int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+ int ph_GL_LoadLibrary(_THIS, const char* path);
+ void* ph_GL_GetProcAddress(_THIS, const char* proc);
+ int ph_GL_MakeCurrent(_THIS);
+
+ int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
+#endif /* SDL_VIDEO_OPENGL */
+
+#endif /* __SDL_PH_GL_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image.c
new file mode 100644
index 0000000..7d64970
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image.c
@@ -0,0 +1,1059 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <Ph.h>
+#include <photon/Pg.h>
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "../SDL_pixels_c.h"
+#include "SDL_ph_video.h"
+#include "SDL_ph_image_c.h"
+#include "SDL_ph_modes_c.h"
+#include "SDL_ph_gl.h"
+
+int ph_SetupImage(_THIS, SDL_Surface *screen)
+{
+ PgColor_t* palette=NULL;
+ int type=0;
+ int bpp;
+
+ bpp=screen->format->BitsPerPixel;
+
+ /* Determine image type */
+ switch(bpp)
+ {
+ case 8:{
+ type = Pg_IMAGE_PALETTE_BYTE;
+ }
+ break;
+ case 15:{
+ type = Pg_IMAGE_DIRECT_555;
+ }
+ break;
+ case 16:{
+ type = Pg_IMAGE_DIRECT_565;
+ }
+ break;
+ case 24:{
+ type = Pg_IMAGE_DIRECT_888;
+ }
+ break;
+ case 32:{
+ type = Pg_IMAGE_DIRECT_8888;
+ }
+ break;
+ default:{
+ SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp);
+ return -1;
+ }
+ break;
+ }
+
+ /* palette emulation code */
+ if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE))
+ {
+ /* creating image palette */
+ palette=SDL_malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
+ if (palette==NULL)
+ {
+ SDL_SetError("ph_SetupImage(): can't allocate memory for palette !\n");
+ return -1;
+ }
+ PgGetPalette(palette);
+
+ /* using shared memory for speed (set last param to 1) */
+ if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
+ {
+ SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n");
+ SDL_free(palette);
+ return -1;
+ }
+ }
+ else
+ {
+ /* using shared memory for speed (set last param to 1) */
+ if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
+ {
+ SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n", bpp);
+ return -1;
+ }
+ }
+
+ screen->pixels = SDL_Image->image;
+ screen->pitch = SDL_Image->bpl;
+
+ this->UpdateRects = ph_NormalUpdate;
+
+ return 0;
+}
+
+int ph_SetupOCImage(_THIS, SDL_Surface *screen)
+{
+ int type = 0;
+ int bpp;
+
+ OCImage.flags = screen->flags;
+
+ bpp=screen->format->BitsPerPixel;
+
+ /* Determine image type */
+ switch(bpp)
+ {
+ case 8: {
+ type = Pg_IMAGE_PALETTE_BYTE;
+ }
+ break;
+ case 15:{
+ type = Pg_IMAGE_DIRECT_555;
+ }
+ break;
+ case 16:{
+ type = Pg_IMAGE_DIRECT_565;
+ }
+ break;
+ case 24:{
+ type = Pg_IMAGE_DIRECT_888;
+ }
+ break;
+ case 32:{
+ type = Pg_IMAGE_DIRECT_8888;
+ }
+ break;
+ default:{
+ SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
+ return -1;
+ }
+ break;
+ }
+
+ /* Currently offscreen contexts with the same bit depth as display bpp only can be created */
+ OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
+
+ if (OCImage.offscreen_context == NULL)
+ {
+ SDL_SetError("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n");
+ return -1;
+ }
+
+ screen->pitch = OCImage.offscreen_context->pitch;
+
+ OCImage.dc_ptr = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
+
+ if (OCImage.dc_ptr == NULL)
+ {
+ SDL_SetError("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n");
+ PhDCRelease(OCImage.offscreen_context);
+ return -1;
+ }
+
+ OCImage.FrameData0 = OCImage.dc_ptr;
+ OCImage.CurrentFrameData = OCImage.FrameData0;
+ OCImage.current = 0;
+
+ PhDCSetCurrent(OCImage.offscreen_context);
+
+ screen->pixels = OCImage.CurrentFrameData;
+
+ this->UpdateRects = ph_OCUpdate;
+
+ return 0;
+}
+
+int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen)
+{
+ OCImage.flags = screen->flags;
+
+ /* Begin direct and fullscreen mode */
+ if (!ph_EnterFullScreen(this, screen, PH_ENTER_DIRECTMODE))
+ {
+ return -1;
+ }
+
+ /* store palette for fullscreen */
+ if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
+ {
+ PgGetPalette(savedpal);
+ PgGetPalette(syspalph);
+ }
+
+ OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY | Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
+ if (OCImage.offscreen_context == NULL)
+ {
+ SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n");
+ return -1;
+ }
+
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
+ if (OCImage.offscreen_backcontext == NULL)
+ {
+ SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n");
+ return -1;
+ }
+ }
+
+ OCImage.FrameData0 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
+ if (OCImage.FrameData0 == NULL)
+ {
+ SDL_SetError("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n");
+ ph_DestroyImage(this, screen);
+ return -1;
+ }
+
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.FrameData1 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_backcontext);
+ if (OCImage.FrameData1 == NULL)
+ {
+ SDL_SetError("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n");
+ ph_DestroyImage(this, screen);
+ return -1;
+ }
+ }
+
+ /* wait for the hardware */
+ PgFlush();
+ PgWaitHWIdle();
+
+ if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
+ {
+ OCImage.current = 0;
+ PhDCSetCurrent(OCImage.offscreen_context);
+ screen->pitch = OCImage.offscreen_context->pitch;
+ screen->pixels = OCImage.FrameData0;
+
+ /* emulate 640x400 videomode */
+ if (videomode_emulatemode==1)
+ {
+ int i;
+
+ for (i=0; i<40; i++)
+ {
+ SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+ }
+ for (i=440; i<480; i++)
+ {
+ SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+ }
+ screen->pixels+=screen->pitch*40;
+ }
+ PgSwapDisplay(OCImage.offscreen_backcontext, 0);
+ }
+ else
+ {
+ OCImage.current = 0;
+ PhDCSetCurrent(OCImage.offscreen_context);
+ screen->pitch = OCImage.offscreen_context->pitch;
+ screen->pixels = OCImage.FrameData0;
+
+ /* emulate 640x400 videomode */
+ if (videomode_emulatemode==1)
+ {
+ int i;
+
+ for (i=0; i<40; i++)
+ {
+ SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+ }
+ for (i=440; i<480; i++)
+ {
+ SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+ }
+ screen->pixels+=screen->pitch*40;
+ }
+ }
+
+ this->UpdateRects = ph_OCDCUpdate;
+
+ /* wait for the hardware */
+ PgFlush();
+ PgWaitHWIdle();
+
+ return 0;
+}
+
+#if SDL_VIDEO_OPENGL
+
+int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
+{
+ this->UpdateRects = ph_OpenGLUpdate;
+ screen->pixels=NULL;
+ screen->pitch=NULL;
+
+ #if (_NTO_VERSION >= 630)
+ if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ if (!ph_EnterFullScreen(this, screen, PH_IGNORE_DIRECTMODE))
+ {
+ screen->flags &= ~SDL_FULLSCREEN;
+ return -1;
+ }
+ }
+ #endif /* 6.3.0 */
+
+ if (ph_SetupOpenGLContext(this, screen->w, screen->h, screen->format->BitsPerPixel, screen->flags)!=0)
+ {
+ screen->flags &= ~SDL_OPENGL;
+ return -1;
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_OPENGL */
+
+void ph_DestroyImage(_THIS, SDL_Surface* screen)
+{
+
+#if SDL_VIDEO_OPENGL
+ if ((screen->flags & SDL_OPENGL)==SDL_OPENGL)
+ {
+ if (oglctx)
+ {
+ #if (_NTO_VERSION < 630)
+ PhDCSetCurrent(NULL);
+ PhDCRelease(oglctx);
+ #else
+ qnxgl_context_destroy(oglctx);
+ qnxgl_buffers_destroy(oglbuffers);
+ qnxgl_finish();
+ #endif /* 6.3.0 */
+ oglctx=NULL;
+ oglbuffers=NULL;
+ oglflags=0;
+ oglbpp=0;
+ }
+
+ #if (_NTO_VERSION >= 630)
+ if (currently_fullscreen)
+ {
+ ph_LeaveFullScreen(this);
+ }
+ #endif /* 6.3.0 */
+
+ return;
+ }
+#endif /* SDL_VIDEO_OPENGL */
+
+ if (currently_fullscreen)
+ {
+ /* if we right now in 8bpp fullscreen we must release palette */
+ if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
+ {
+ PgSetPalette(syspalph, 0, -1, 0, 0, 0);
+ PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
+ PgFlush();
+ }
+ ph_LeaveFullScreen(this);
+ }
+
+ if (OCImage.offscreen_context != NULL)
+ {
+ PhDCRelease(OCImage.offscreen_context);
+ OCImage.offscreen_context = NULL;
+ OCImage.FrameData0 = NULL;
+ }
+ if (OCImage.offscreen_backcontext != NULL)
+ {
+ PhDCRelease(OCImage.offscreen_backcontext);
+ OCImage.offscreen_backcontext = NULL;
+ OCImage.FrameData1 = NULL;
+ }
+ OCImage.CurrentFrameData = NULL;
+
+ if (SDL_Image)
+ {
+ /* if palette allocated, free it */
+ if (SDL_Image->palette)
+ {
+ SDL_free(SDL_Image->palette);
+ }
+ PgShmemDestroy(SDL_Image->image);
+ SDL_free(SDL_Image);
+ }
+
+ /* Must be zeroed everytime */
+ SDL_Image = NULL;
+
+ if (screen)
+ {
+ screen->pixels = NULL;
+ }
+}
+
+int ph_UpdateHWInfo(_THIS)
+{
+ PgVideoModeInfo_t vmode;
+ PgHWCaps_t hwcaps;
+
+ /* Update video ram amount */
+ if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+ {
+ SDL_SetError("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n");
+ return -1;
+ }
+ this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
+ /* obtain current mode capabilities */
+ if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0)
+ {
+ SDL_SetError("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n");
+ return -1;
+ }
+
+ if ((vmode.mode_capabilities1 & PgVM_MODE_CAP1_OFFSCREEN) == PgVM_MODE_CAP1_OFFSCREEN)
+ {
+ /* this is a special test for drivers which tries to lie about offscreen capability */
+ if (hwcaps.currently_available_video_ram!=0)
+ {
+ this->info.hw_available = 1;
+ }
+ else
+ {
+ this->info.hw_available = 0;
+ }
+ }
+ else
+ {
+ this->info.hw_available = 0;
+ }
+
+ if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_RECTANGLE) == PgVM_MODE_CAP2_RECTANGLE)
+ {
+ this->info.blit_fill = 1;
+ }
+ else
+ {
+ this->info.blit_fill = 0;
+ }
+
+ if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_BITBLT) == PgVM_MODE_CAP2_BITBLT)
+ {
+ this->info.blit_hw = 1;
+ }
+ else
+ {
+ this->info.blit_hw = 0;
+ }
+
+ if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) == PgVM_MODE_CAP2_ALPHA_BLEND)
+ {
+ this->info.blit_hw_A = 1;
+ }
+ else
+ {
+ this->info.blit_hw_A = 0;
+ }
+
+ if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) == PgVM_MODE_CAP2_CHROMA)
+ {
+ this->info.blit_hw_CC = 1;
+ }
+ else
+ {
+ this->info.blit_hw_CC = 0;
+ }
+
+ return 0;
+}
+
+int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags)
+{
+ int setupresult=-1;
+
+ ph_DestroyImage(this, screen);
+
+#if SDL_VIDEO_OPENGL
+ if ((flags & SDL_OPENGL)==SDL_OPENGL)
+ {
+ setupresult=ph_SetupOpenGLImage(this, screen);
+ }
+ else
+ {
+#endif
+ if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
+ {
+ setupresult=ph_SetupFullScreenImage(this, screen);
+ }
+ else
+ {
+ if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
+ {
+ setupresult=ph_SetupOCImage(this, screen);
+ }
+ else
+ {
+ setupresult=ph_SetupImage(this, screen);
+ }
+ }
+#if SDL_VIDEO_OPENGL
+ }
+#endif
+ if (setupresult!=-1)
+ {
+ ph_UpdateHWInfo(this);
+ }
+
+ return setupresult;
+}
+
+int ph_AllocHWSurface(_THIS, SDL_Surface* surface)
+{
+ PgHWCaps_t hwcaps;
+
+ if (surface->hwdata!=NULL)
+ {
+ SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n");
+ return -1;
+ }
+ surface->hwdata=SDL_malloc(sizeof(struct private_hwdata));
+ SDL_memset(surface->hwdata, 0x00, sizeof(struct private_hwdata));
+ surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN);
+ if (surface->hwdata->offscreenctx == NULL)
+ {
+ SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n");
+ return -1;
+ }
+ surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx);
+ if (surface->pixels==NULL)
+ {
+ PhDCRelease(surface->hwdata->offscreenctx);
+ SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n");
+ return -1;
+ }
+ surface->pitch=surface->hwdata->offscreenctx->pitch;
+ surface->flags|=SDL_HWSURFACE;
+ surface->flags|=SDL_PREALLOC;
+
+#if 0 /* FIXME */
+ /* create simple offscreen lock */
+ surface->hwdata->crlockparam.flags=0;
+ if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK)
+ {
+ PhDCRelease(surface->hwdata->offscreenctx);
+ SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n");
+ return -1;
+ }
+#endif /* 0 */
+
+ /* Update video ram amount */
+ if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+ {
+ PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
+ PhDCRelease(surface->hwdata->offscreenctx);
+ SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n");
+ return -1;
+ }
+ this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
+ return 0;
+}
+
+void ph_FreeHWSurface(_THIS, SDL_Surface* surface)
+{
+ PgHWCaps_t hwcaps;
+
+ if (surface->hwdata==NULL)
+ {
+ SDL_SetError("ph_FreeHWSurface(): no hwdata!\n");
+ return;
+ }
+ if (surface->hwdata->offscreenctx == NULL)
+ {
+ SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n");
+ return;
+ }
+
+#if 0 /* FIXME */
+ /* unlock the offscreen context if it has been locked before destroy it */
+ if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
+ {
+ PdUnlockOffscreen(surface->hwdata->offscreenctx);
+ }
+
+ PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
+#endif /* 0 */
+
+ PhDCRelease(surface->hwdata->offscreenctx);
+
+ SDL_free(surface->hwdata);
+ surface->hwdata=NULL;
+
+ /* Update video ram amount */
+ if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+ {
+ SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n");
+ return;
+ }
+ this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
+ return;
+}
+
+int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ if ((src->hwdata==NULL) && (src != this->screen))
+ {
+ SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n");
+ src->flags&=~SDL_HWACCEL;
+ return -1;
+ }
+ if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE)
+ {
+ SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n");
+ src->flags&=~SDL_HWACCEL;
+ return -1;
+ }
+
+ if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+ {
+ if (this->info.blit_hw_CC!=1)
+ {
+ src->flags&=~SDL_HWACCEL;
+ src->map->hw_blit=NULL;
+ return -1;
+ }
+ }
+
+ if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
+ {
+ if (this->info.blit_hw_A!=1)
+ {
+ src->flags&=~SDL_HWACCEL;
+ src->map->hw_blit=NULL;
+ return -1;
+ }
+ }
+
+ src->flags|=SDL_HWACCEL;
+ src->map->hw_blit = ph_HWAccelBlit;
+
+ return 1;
+}
+
+PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color)
+{
+ Uint32 truecolor;
+
+ /* Photon API accepts true colors only during hw filling operations */
+ switch(surface->format->BitsPerPixel)
+ {
+ case 8:
+ {
+ if ((surface->format->palette) && (color<=surface->format->palette->ncolors))
+ {
+ truecolor=PgRGB(surface->format->palette->colors[color].r,
+ surface->format->palette->colors[color].g,
+ surface->format->palette->colors[color].b);
+ }
+ else
+ {
+ SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n");
+ return 0xFFFFFFFFUL;
+ }
+ }
+ break;
+ case 15:
+ {
+ truecolor = ((color & 0x00007C00UL) << 9) | /* R */
+ ((color & 0x000003E0UL) << 6) | /* G */
+ ((color & 0x0000001FUL) << 3) | /* B */
+ ((color & 0x00007000UL) << 4) | /* R compensation */
+ ((color & 0x00000380UL) << 1) | /* G compensation */
+ ((color & 0x0000001CUL) >> 2); /* B compensation */
+ }
+ break;
+ case 16:
+ {
+ truecolor = ((color & 0x0000F800UL) << 8) | /* R */
+ ((color & 0x000007E0UL) << 5) | /* G */
+ ((color & 0x0000001FUL) << 3) | /* B */
+ ((color & 0x0000E000UL) << 3) | /* R compensation */
+ ((color & 0x00000600UL) >> 1) | /* G compensation */
+ ((color & 0x0000001CUL) >> 2); /* B compensation */
+
+ }
+ break;
+ case 24:
+ {
+ truecolor=color & 0x00FFFFFFUL;
+ }
+ break;
+ case 32:
+ {
+ truecolor=color;
+ }
+ break;
+ default:
+ {
+ SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n");
+ return 0xFFFFFFFFUL;
+ }
+ }
+
+ return truecolor;
+}
+
+int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color)
+{
+ PgColor_t oldcolor;
+ Uint32 truecolor;
+ int ydisp=0;
+
+ if (this->info.blit_fill!=1)
+ {
+ return -1;
+ }
+
+ truecolor=ph_ExpandColor(this, surface, color);
+ if (truecolor==0xFFFFFFFFUL)
+ {
+ return -1;
+ }
+
+ oldcolor=PgSetFillColor(truecolor);
+
+ /* 640x400 videomode emulation */
+ if (videomode_emulatemode==1)
+ {
+ ydisp+=40;
+ }
+
+ PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL);
+ PgSetFillColor(oldcolor);
+ PgFlush();
+ PgWaitHWIdle();
+
+ return 0;
+}
+
+int ph_FlipHWSurface(_THIS, SDL_Surface* screen)
+{
+ PhArea_t farea;
+
+ if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ /* flush all drawing ops before blitting */
+ PgFlush();
+ PgWaitHWIdle();
+
+ farea.pos.x=0;
+ farea.pos.y=0;
+ farea.size.w=screen->w;
+ farea.size.h=screen->h;
+
+ /* emulate 640x400 videomode */
+ if (videomode_emulatemode==1)
+ {
+ farea.pos.y+=40;
+ }
+
+ PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea);
+
+ /* flush the blitting */
+ PgFlush();
+ PgWaitHWIdle();
+ }
+ return 0;
+}
+
+int ph_LockHWSurface(_THIS, SDL_Surface* surface)
+{
+
+#if 0 /* FIXME */
+ int lockresult;
+
+ if (surface->hwdata == NULL)
+ {
+ return;
+ }
+
+ surface->hwdata->lockparam.flags=0;
+ surface->hwdata->lockparam.time_out=NULL;
+ lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam);
+
+ switch (lockresult)
+ {
+ case EOK:
+ break;
+ case Pg_OSC_LOCK_DEADLOCK:
+ SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n");
+ return -1;
+ case Pg_OSC_LOCK_INVALID:
+ SDL_SetError("ph_LockHWSurface(): Lock invalid !\n");
+ return -1;
+ default:
+ SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n");
+ return -1;
+ }
+#endif /* 0 */
+
+ return 0;
+}
+
+void ph_UnlockHWSurface(_THIS, SDL_Surface* surface)
+{
+
+#if 0 /* FIXME */
+ int unlockresult;
+
+ if ((surface == NULL) || (surface->hwdata == NULL))
+ {
+ return;
+ }
+
+ if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
+ {
+ unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx);
+ }
+#endif /* 0 */
+
+ return;
+}
+
+int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect)
+{
+ SDL_VideoDevice* this=current_video;
+ PhArea_t srcarea;
+ PhArea_t dstarea;
+ int ydisp=0;
+
+ /* 640x400 videomode emulation */
+ if (videomode_emulatemode==1)
+ {
+ ydisp+=40;
+ }
+
+ srcarea.pos.x=srcrect->x;
+ srcarea.pos.y=srcrect->y;
+ srcarea.size.w=srcrect->w;
+ srcarea.size.h=srcrect->h;
+
+ dstarea.pos.x=dstrect->x;
+ dstarea.pos.y=dstrect->y;
+ dstarea.size.w=dstrect->w;
+ dstarea.size.h=dstrect->h;
+
+ if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL)))
+ {
+ if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+ {
+ ph_SetHWColorKey(this, src, src->format->colorkey);
+ PgChromaOn();
+ }
+
+ if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
+ {
+ ph_SetHWAlpha(this, src, src->format->alpha);
+ PgAlphaOn();
+ }
+
+ if (dst == this->screen)
+ {
+ if (src == this->screen)
+ {
+ /* blitting from main screen to main screen */
+ dstarea.pos.y+=ydisp;
+ srcarea.pos.y+=ydisp;
+ PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea);
+ }
+ else
+ {
+ /* blitting from offscreen to main screen */
+ dstarea.pos.y+=ydisp;
+ PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea);
+ }
+ }
+ else
+ {
+ if (src == this->screen)
+ {
+ /* blitting from main screen to offscreen */
+ srcarea.pos.y+=ydisp;
+ PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea);
+ }
+ else
+ {
+ /* blitting offscreen to offscreen */
+ PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea);
+ }
+ }
+
+ if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
+ {
+ PgAlphaOff();
+ }
+
+ if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+ {
+ PgChromaOff();
+ }
+ }
+ else
+ {
+ SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n");
+ return -1;
+ }
+
+ PgFlush();
+ PgWaitHWIdle();
+
+ return 0;
+}
+
+int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ if (this->info.blit_hw_CC!=1)
+ {
+ return -1;
+ }
+
+ if (surface->hwdata!=NULL)
+ {
+ surface->hwdata->colorkey=ph_ExpandColor(this, surface, key);
+ if (surface->hwdata->colorkey==0xFFFFFFFFUL)
+ {
+ return -1;
+ }
+ }
+ PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
+
+ return 0;
+}
+
+int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha)
+{
+ if (this->info.blit_hw_A!=1)
+ {
+ return -1;
+ }
+
+ PgSetAlphaBlend(NULL, alpha);
+
+ return 0;
+}
+
+#if SDL_VIDEO_OPENGL
+void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects)
+{
+ this->GL_SwapBuffers(this);
+
+ return;
+}
+#endif /* SDL_VIDEO_OPENGL */
+
+void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ PhPoint_t ph_pos;
+ PhRect_t ph_rect;
+ int i;
+
+ for (i=0; i<numrects; ++i)
+ {
+ if (rects[i].w==0) /* Clipped? dunno why but this occurs sometime. */
+ {
+ continue;
+ }
+
+ if (rects[i].h==0) /* Clipped? dunno why but this occurs sometime. */
+ {
+ continue;
+ }
+
+ ph_pos.x = rects[i].x;
+ ph_pos.y = rects[i].y;
+ ph_rect.ul.x = rects[i].x;
+ ph_rect.ul.y = rects[i].y;
+ ph_rect.lr.x = rects[i].x + rects[i].w;
+ ph_rect.lr.y = rects[i].y + rects[i].h;
+
+ if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
+ {
+ SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n");
+ return;
+ }
+ }
+
+ if (PgFlush() < 0)
+ {
+ SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n");
+ }
+}
+
+void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i;
+
+ PhPoint_t zero = {0, 0};
+ PhArea_t src_rect;
+ PhArea_t dest_rect;
+
+ PgSetTranslation(&zero, 0);
+ PgSetRegion(PtWidgetRid(window));
+ PgSetClipping(0, NULL);
+
+ PgFlush();
+ PgWaitHWIdle();
+
+ for (i=0; i<numrects; ++i)
+ {
+ if (rects[i].w == 0) /* Clipped? */
+ {
+ continue;
+ }
+
+ if (rects[i].h == 0) /* Clipped? */
+ {
+ continue;
+ }
+
+ src_rect.pos.x=rects[i].x;
+ src_rect.pos.y=rects[i].y;
+ dest_rect.pos.x=rects[i].x;
+ dest_rect.pos.y=rects[i].y;
+
+ src_rect.size.w=rects[i].w;
+ src_rect.size.h=rects[i].h;
+ dest_rect.size.w=rects[i].w;
+ dest_rect.size.h=rects[i].h;
+
+ PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
+ }
+
+ if (PgFlush() < 0)
+ {
+ SDL_SetError("ph_OCUpdate(): PgFlush failed.\n");
+ }
+}
+
+void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ PgWaitHWIdle();
+
+ if (PgFlush() < 0)
+ {
+ SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n");
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image_c.h
new file mode 100644
index 0000000..cfd9669
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_image_c.h
@@ -0,0 +1,59 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_IMAGE_H__
+#define __SDL_PH_IMAGE_H__
+
+#include "../../events/SDL_events_c.h"
+#include "SDL_ph_video.h"
+
+struct private_hwdata
+{
+ PdOffscreenContext_t* offscreenctx;
+ PdOSCCreateLockParams_t crlockparam;
+ PdOSCLockParams_t lockparam;
+ Uint32 colorkey;
+};
+
+extern int ph_SetupImage(_THIS, SDL_Surface* screen);
+extern void ph_DestroyImage(_THIS, SDL_Surface* screen);
+extern int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags);
+
+extern int ph_AllocHWSurface(_THIS, SDL_Surface* surface);
+extern void ph_FreeHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
+extern int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color);
+extern int ph_LockHWSurface(_THIS, SDL_Surface* surface);
+extern void ph_UnlockHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_FlipHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_SetHWColorKey(_THIS, SDL_Surface* surface, Uint32 key);
+extern int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha);
+extern int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect *srcrect, SDL_Surface* dst, SDL_Rect* dstrect);
+extern int ph_UpdateHWInfo(_THIS);
+
+extern void ph_NormalUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OCUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects);
+
+#endif /* __SDL_PH_IMAGE_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes.c
new file mode 100644
index 0000000..8c2bf7e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes.c
@@ -0,0 +1,390 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_ph_modes_c.h"
+
+static PgVideoModeInfo_t mode_info;
+static PgVideoModes_t mode_list;
+
+/* The current list of available video modes */
+SDL_Rect SDL_modelist[PH_MAX_VIDEOMODES];
+SDL_Rect* SDL_modearray[PH_MAX_VIDEOMODES];
+
+static int compare_modes_by_res(const void* mode1, const void* mode2)
+{
+ PgVideoModeInfo_t mode1_info;
+ PgVideoModeInfo_t mode2_info;
+
+ if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode1_info) < 0)
+ {
+ return 0;
+ }
+
+ if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode2_info) < 0)
+ {
+ return 0;
+ }
+
+ if (mode1_info.width == mode2_info.width)
+ {
+ return mode2_info.height - mode1_info.height;
+ }
+ else
+ {
+ return mode2_info.width - mode1_info.width;
+ }
+}
+
+SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ int i = 0;
+ int j = 0;
+ SDL_Rect Amodelist[PH_MAX_VIDEOMODES];
+
+ for (i=0; i<PH_MAX_VIDEOMODES; i++)
+ {
+ SDL_modearray[i]=&SDL_modelist[i];
+ }
+
+ if (PgGetVideoModeList(&mode_list) < 0)
+ {
+ SDL_SetError("ph_ListModes(): PgGetVideoModeList() function failed !\n");
+ return NULL;
+ }
+
+ mode_info.bits_per_pixel = 0;
+
+ for (i=0; i < mode_list.num_modes; i++)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ SDL_SetError("ph_ListModes(): PgGetVideoModeInfo() function failed on mode: 0x%X.\n", mode_list.modes[i]);
+ return NULL;
+ }
+ if(mode_info.bits_per_pixel == format->BitsPerPixel)
+ {
+ Amodelist[j].w = mode_info.width;
+ Amodelist[j].h = mode_info.height;
+ Amodelist[j].x = 0;
+ Amodelist[j].y = 0;
+ j++;
+ }
+ }
+
+ /* reorder biggest for smallest, assume width dominates */
+
+ for(i=0; i<j; i++)
+ {
+ SDL_modelist[i].w = Amodelist[j - i - 1].w;
+ SDL_modelist[i].h = Amodelist[j - i - 1].h;
+ SDL_modelist[i].x = Amodelist[j - i - 1].x;
+ SDL_modelist[i].y = Amodelist[j - i - 1].y;
+ }
+ SDL_modearray[j]=NULL;
+
+ return SDL_modearray;
+}
+
+void ph_FreeVideoModes(_THIS)
+{
+ return;
+}
+
+/* return the mode associated with width, height and bpp */
+/* if there is no mode then zero is returned */
+int ph_GetVideoMode(int width, int height, int bpp)
+{
+ int i;
+ int modestage=0;
+ int closestmode=0;
+
+ if (PgGetVideoModeList(&mode_list) < 0)
+ {
+ return -1;
+ }
+
+ /* special case for the double-sized 320x200 mode */
+ if ((width==640) && (height==400))
+ {
+ modestage=1;
+ }
+
+ /* search list for exact match */
+ for (i=0; i<mode_list.num_modes; i++)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ return 0;
+ }
+
+ if ((mode_info.width == width) && (mode_info.height == height) &&
+ (mode_info.bits_per_pixel == bpp))
+ {
+ return mode_list.modes[i];
+ }
+ else
+ {
+ if ((modestage) && (mode_info.width == width) && (mode_info.height == height+80) &&
+ (mode_info.bits_per_pixel == bpp))
+ {
+ modestage=2;
+ closestmode=mode_list.modes[i];
+ }
+ }
+ }
+
+ /* if we are here, then no 640x400xbpp mode found and we'll emulate it via 640x480xbpp mode */
+ if (modestage==2)
+ {
+ return closestmode;
+ }
+
+ return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
+}
+
+/* return the mode associated with width, height and bpp */
+/* if requested bpp is not found the mode with closest bpp is returned */
+int get_mode_any_format(int width, int height, int bpp)
+{
+ int i, closest, delta, min_delta;
+
+ if (PgGetVideoModeList(&mode_list) < 0)
+ {
+ return -1;
+ }
+
+ SDL_qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
+
+ for(i=0;i<mode_list.num_modes;i++)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ return 0;
+ }
+ if ((mode_info.width == width) && (mode_info.height == height))
+ {
+ break;
+ }
+ }
+
+ if (i<mode_list.num_modes)
+ {
+ /* get closest bpp */
+ closest = i++;
+ if (mode_info.bits_per_pixel == bpp)
+ {
+ return mode_list.modes[closest];
+ }
+
+ min_delta = abs(mode_info.bits_per_pixel - bpp);
+
+ while(1)
+ {
+ if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
+ {
+ return 0;
+ }
+
+ if ((mode_info.width != width) || (mode_info.height != height))
+ {
+ break;
+ }
+ else
+ {
+ if (mode_info.bits_per_pixel == bpp)
+ {
+ closest = i;
+ break;
+ }
+ else
+ {
+ delta = abs(mode_info.bits_per_pixel - bpp);
+ if (delta < min_delta)
+ {
+ closest = i;
+ min_delta = delta;
+ }
+ i++;
+ }
+ }
+ }
+ return mode_list.modes[closest];
+ }
+
+ return 0;
+}
+
+int ph_ToggleFullScreen(_THIS, int on)
+{
+ return -1;
+}
+
+int ph_EnterFullScreen(_THIS, SDL_Surface* screen, int fmode)
+{
+ PgDisplaySettings_t settings;
+ int mode;
+ char* refreshrate;
+ int refreshratenum;
+
+ if (!currently_fullscreen)
+ {
+ /* Get the video mode and set it */
+ if (screen->flags & SDL_ANYFORMAT)
+ {
+ if ((mode = get_mode_any_format(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
+ return 0;
+ }
+ }
+ else
+ {
+ if ((mode = ph_GetVideoMode(screen->w, screen->h, screen->format->BitsPerPixel)) == 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
+ return 0;
+ }
+ if (PgGetVideoModeInfo(mode, &mode_info) < 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): can't get video mode capabilities !\n");
+ return 0;
+ }
+ if (mode_info.height != screen->h)
+ {
+ if ((mode_info.height==480) && (screen->h==400))
+ {
+ videomode_emulatemode=1;
+ }
+ }
+ else
+ {
+ videomode_emulatemode=0;
+ }
+ }
+
+ /* save old video mode caps */
+ PgGetVideoMode(&settings);
+ old_video_mode=settings.mode;
+ old_refresh_rate=settings.refresh;
+
+ /* setup new video mode */
+ settings.mode = mode;
+ settings.refresh = 0;
+ settings.flags = 0;
+
+ refreshrate=SDL_getenv("SDL_PHOTON_FULLSCREEN_REFRESH");
+ if (refreshrate!=NULL)
+ {
+ if (SDL_sscanf(refreshrate, "%d", &refreshratenum)==1)
+ {
+ settings.refresh = refreshratenum;
+ }
+ }
+
+ if (PgSetVideoMode(&settings) < 0)
+ {
+ SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n");
+ return 0;
+ }
+
+ if (this->screen)
+ {
+ if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
+ {
+#if !SDL_VIDEO_OPENGL || (_NTO_VERSION < 630)
+ return 0; /* 6.3.0 */
+#endif
+ }
+ }
+
+ if (fmode==0)
+ {
+ if (OCImage.direct_context==NULL)
+ {
+ OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
+ if (!OCImage.direct_context)
+ {
+ SDL_SetError("ph_EnterFullScreen(): Can't create direct context !\n");
+ ph_LeaveFullScreen(this);
+ return 0;
+ }
+ }
+ OCImage.oldDC=PdDirectStart(OCImage.direct_context);
+ }
+
+ currently_fullscreen = 1;
+ }
+ PgFlush();
+
+ return 1;
+}
+
+int ph_LeaveFullScreen(_THIS)
+{
+ PgDisplaySettings_t oldmode_settings;
+
+ if (currently_fullscreen)
+ {
+ if ((this->screen) && ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL))
+ {
+#if !SDL_VIDEO_OPENGL || (_NTO_VERSION < 630)
+ return 0;
+#endif
+ }
+
+ /* release routines starts here */
+ {
+ if (OCImage.direct_context)
+ {
+ PdDirectStop(OCImage.direct_context);
+ PdReleaseDirectContext(OCImage.direct_context);
+ OCImage.direct_context=NULL;
+ }
+ if (OCImage.oldDC)
+ {
+ PhDCSetCurrent(OCImage.oldDC);
+ OCImage.oldDC=NULL;
+ }
+
+ currently_fullscreen=0;
+
+ /* Restore old video mode */
+ if (old_video_mode != -1)
+ {
+ oldmode_settings.mode = (unsigned short) old_video_mode;
+ oldmode_settings.refresh = (unsigned short) old_refresh_rate;
+ oldmode_settings.flags = 0;
+
+ if (PgSetVideoMode(&oldmode_settings) < 0)
+ {
+ SDL_SetError("Ph_LeaveFullScreen(): PgSetVideoMode() function failed !\n");
+ return 0;
+ }
+ }
+
+ old_video_mode=-1;
+ old_refresh_rate=-1;
+ }
+ }
+ return 1;
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes_c.h
new file mode 100644
index 0000000..117c5a3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_modes_c.h
@@ -0,0 +1,43 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_MODES_H__
+#define __SDL_PH_MODES_H__
+
+#include "SDL_ph_video.h"
+
+#define PH_MAX_VIDEOMODES 127
+
+#define PH_ENTER_DIRECTMODE 0
+#define PH_IGNORE_DIRECTMODE 1
+
+extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags);
+extern void ph_FreeVideoModes(_THIS);
+extern int ph_ResizeFullScreen(_THIS);
+extern int ph_EnterFullScreen(_THIS, SDL_Surface* screen, int fmode);
+extern int ph_LeaveFullScreen(_THIS);
+extern int ph_GetVideoMode(int width, int height, int bpp);
+extern int get_mode_any_format(int width, int height, int bpp);
+extern int ph_ToggleFullScreen(_THIS, int on);
+
+#endif /* __SDL_PH_MODES_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse.c
new file mode 100644
index 0000000..a25aa1f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse.c
@@ -0,0 +1,220 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_ph_mouse_c.h"
+
+struct WMcursor
+{
+ PhCursorDef_t *ph_cursor ;
+};
+
+void ph_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ if (window != NULL)
+ {
+ SDL_Lock_EventThread();
+
+ if (PtSetResource(window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0)
+ {
+ /* TODO: output error msg */
+ }
+
+ SDL_Unlock_EventThread();
+ }
+
+ SDL_free(cursor);
+}
+
+WMcursor *ph_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor* cursor;
+ int clen, i;
+ unsigned char bit, databit, maskbit;
+
+ /* Allocate and initialize the cursor memory */
+ if ((cursor = (WMcursor*)SDL_malloc(sizeof(WMcursor))) == NULL)
+ {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(cursor,0,sizeof(WMcursor));
+
+ cursor->ph_cursor = (PhCursorDef_t *) SDL_malloc(sizeof(PhCursorDef_t) + 32*4*2);
+
+ if (cursor->ph_cursor == NULL)
+ {
+ SDL_SetError("ph_CreateWMCursor(): cursor malloc failed !\n");
+ return NULL;
+ }
+
+ SDL_memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2));
+
+ cursor->ph_cursor->hdr.type =Ph_RDATA_CURSOR;
+ cursor->ph_cursor->size1.x = (short)w;
+ cursor->ph_cursor->size1.y = (short)h;
+ cursor->ph_cursor->offset1.x = (short)hot_x;
+ cursor->ph_cursor->offset1.y = (short)hot_y;
+ cursor->ph_cursor->bytesperline1 = (char)w/8;
+ cursor->ph_cursor->color1 = Pg_WHITE;
+ cursor->ph_cursor->size2.x = (short)w;
+ cursor->ph_cursor->size2.y = (short)h;
+ cursor->ph_cursor->offset2.x = (short)hot_x;
+ cursor->ph_cursor->offset2.y = (short)hot_y;
+ cursor->ph_cursor->bytesperline2 = (char)w/8;
+ cursor->ph_cursor->color2 = Pg_BLACK;
+
+ clen = (w/8)*h;
+
+ /* Copy the mask and the data to different bitmap planes */
+ for (i=0; i<clen; ++i)
+ {
+ for (bit = 0; bit < 8; bit++)
+ {
+ databit = data[i] & (1 << bit);
+ maskbit = mask[i] & (1 << bit);
+
+ cursor->ph_cursor->images[i] |= (databit == 0) ? maskbit : 0;
+ /* If the databit != 0, treat it as a black pixel and
+ * ignore the maskbit (can't do an inverted color) */
+ cursor->ph_cursor->images[i+clen] |= databit;
+ }
+ }
+
+ /* #bytes following the hdr struct */
+ cursor->ph_cursor->hdr.len =sizeof(PhCursorDef_t) + clen*2 - sizeof(PhRegionDataHdr_t);
+
+ return (cursor);
+}
+
+PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor)
+{
+ return (*cursor->ph_cursor);
+}
+
+int ph_ShowWMCursor(_THIS, WMcursor* cursor)
+{
+ PtArg_t args[3];
+ int nargs = 0;
+
+ /* Don't do anything if the display is gone */
+ if (window == NULL)
+ {
+ return (0);
+ }
+
+ /* looks like photon can't draw mouse cursor in direct mode */
+ if ((this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ /* disable the fake mouse in the fullscreen OpenGL mode */
+ if ((this->screen->flags & SDL_OPENGL) == SDL_OPENGL)
+ {
+ cursor=NULL;
+ }
+ else
+ {
+ return (0);
+ }
+ }
+
+ /* Set the photon cursor, or blank if cursor is NULL */
+ if (cursor!=NULL)
+ {
+ PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0);
+ /* Could set next to any PgColor_t value */
+ PtSetArg(&args[1], Pt_ARG_CURSOR_COLOR, Ph_CURSOR_DEFAULT_COLOR , 0);
+ PtSetArg(&args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t)));
+ nargs = 3;
+ }
+ else /* Ph_CURSOR_NONE */
+ {
+ PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
+ nargs = 1;
+ }
+
+ SDL_Lock_EventThread();
+
+ if (PtSetResources(window, nargs, args) < 0 )
+ {
+ return (0);
+ }
+
+ SDL_Unlock_EventThread();
+
+ return (1);
+}
+
+
+void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ short abs_x, abs_y;
+
+ SDL_Lock_EventThread();
+ PtGetAbsPosition( window, &abs_x, &abs_y );
+ PhMoveCursorAbs( PhInputGroup(NULL), x + abs_x, y + abs_y );
+ SDL_Unlock_EventThread();
+}
+
+
+void ph_CheckMouseMode(_THIS)
+{
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) && (this->input_grab != SDL_GRAB_OFF))
+ {
+ mouse_relative = 1;
+ }
+ else
+ {
+ mouse_relative = 0;
+ }
+}
+
+
+void ph_UpdateMouse(_THIS)
+{
+ PhCursorInfo_t phcursor;
+ short abs_x;
+ short abs_y;
+
+ /* Lock the event thread, in multi-threading environments */
+ SDL_Lock_EventThread();
+
+ /* synchronizing photon mouse cursor position and SDL mouse position, if cursor appears over window. */
+ PtGetAbsPosition(window, &abs_x, &abs_y);
+ PhQueryCursor(PhInputGroup(NULL), &phcursor);
+ if (((phcursor.pos.x >= abs_x) && (phcursor.pos.x <= abs_x + this->screen->w)) &&
+ ((phcursor.pos.y >= abs_y) && (phcursor.pos.y <= abs_y + this->screen->h)))
+ {
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ SDL_PrivateMouseMotion(0, 0, phcursor.pos.x-abs_x, phcursor.pos.y-abs_y);
+ }
+ else
+ {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+
+ /* Unlock the event thread, in multi-threading environments */
+ SDL_Unlock_EventThread();
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse_c.h
new file mode 100644
index 0000000..55a92b6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_mouse_c.h
@@ -0,0 +1,39 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_MOUSE_H__
+#define __SDL_PH_MOUSE_H__
+
+#include "SDL_ph_video.h"
+
+/* Functions to be exported */
+extern void ph_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *ph_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor);
+extern int ph_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+extern void ph_CheckMouseMode(_THIS);
+extern void ph_UpdateMouse(_THIS);
+
+#endif /* __SDL_PH_MOUSE_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.c
new file mode 100644
index 0000000..5e1a82b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.c
@@ -0,0 +1,648 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include "SDL_endian.h"
+#include "SDL_timer.h"
+#include "SDL_thread.h"
+#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_ph_video.h"
+#include "SDL_ph_modes_c.h"
+#include "SDL_ph_image_c.h"
+#include "SDL_ph_events_c.h"
+#include "SDL_ph_mouse_c.h"
+#include "SDL_ph_wm_c.h"
+#include "SDL_ph_gl.h"
+#include "SDL_phyuv_c.h"
+#include "../blank_cursor.h"
+
+static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void ph_VideoQuit(_THIS);
+static void ph_DeleteDevice(SDL_VideoDevice *device);
+
+static int phstatus=-1;
+
+static int ph_Available(void)
+{
+ if (phstatus!=0)
+ {
+ phstatus=PtInit(NULL);
+ if (phstatus==0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static SDL_VideoDevice* ph_CreateDevice(int devindex)
+{
+ SDL_VideoDevice* device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if (device)
+ {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData*)SDL_malloc((sizeof *device->hidden));
+ device->gl_data = NULL;
+ }
+ if ((device == NULL) || (device->hidden == NULL))
+ {
+ SDL_OutOfMemory();
+ ph_DeleteDevice(device);
+ return NULL;
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the driver flags */
+ device->handles_any_size = 1;
+
+ /* Set the function pointers */
+ device->CreateYUVOverlay = ph_CreateYUVOverlay;
+ device->VideoInit = ph_VideoInit;
+ device->ListModes = ph_ListModes;
+ device->SetVideoMode = ph_SetVideoMode;
+ device->ToggleFullScreen = ph_ToggleFullScreen;
+ device->UpdateMouse = ph_UpdateMouse;
+ device->SetColors = ph_SetColors;
+ device->UpdateRects = NULL; /* set up in ph_SetupUpdateFunction */
+ device->VideoQuit = ph_VideoQuit;
+ device->AllocHWSurface = ph_AllocHWSurface;
+ device->CheckHWBlit = ph_CheckHWBlit;
+ device->FillHWRect = ph_FillHWRect;
+ device->SetHWColorKey = ph_SetHWColorKey;
+ device->SetHWAlpha = ph_SetHWAlpha;
+ device->LockHWSurface = ph_LockHWSurface;
+ device->UnlockHWSurface = ph_UnlockHWSurface;
+ device->FlipHWSurface = ph_FlipHWSurface;
+ device->FreeHWSurface = ph_FreeHWSurface;
+ device->SetCaption = ph_SetCaption;
+ device->SetIcon = NULL;
+ device->IconifyWindow = ph_IconifyWindow;
+ device->GrabInput = ph_GrabInput;
+ device->GetWMInfo = ph_GetWMInfo;
+ device->FreeWMCursor = ph_FreeWMCursor;
+ device->CreateWMCursor = ph_CreateWMCursor;
+ device->ShowWMCursor = ph_ShowWMCursor;
+ device->WarpWMCursor = ph_WarpWMCursor;
+ device->MoveWMCursor = NULL;
+ device->CheckMouseMode = ph_CheckMouseMode;
+ device->InitOSKeymap = ph_InitOSKeymap;
+ device->PumpEvents = ph_PumpEvents;
+
+ /* OpenGL support. */
+#if SDL_VIDEO_OPENGL
+ device->GL_MakeCurrent = ph_GL_MakeCurrent;
+ device->GL_SwapBuffers = ph_GL_SwapBuffers;
+ device->GL_GetAttribute = ph_GL_GetAttribute;
+ device->GL_LoadLibrary = ph_GL_LoadLibrary;
+ device->GL_GetProcAddress = ph_GL_GetProcAddress;
+#endif /* SDL_VIDEO_OPENGL */
+
+ device->free = ph_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap ph_bootstrap = {
+ "photon", "QNX Photon video output",
+ ph_Available, ph_CreateDevice
+};
+
+static void ph_DeleteDevice(SDL_VideoDevice *device)
+{
+ if (device)
+ {
+ if (device->hidden)
+ {
+ SDL_free(device->hidden);
+ device->hidden = NULL;
+ }
+ if (device->gl_data)
+ {
+ SDL_free(device->gl_data);
+ device->gl_data = NULL;
+ }
+ SDL_free(device);
+ device = NULL;
+ }
+}
+
+static PtWidget_t *ph_CreateWindow(_THIS)
+{
+ PtWidget_t *widget;
+
+ widget = PtCreateWidget(PtWindow, NULL, 0, NULL);
+
+ return widget;
+}
+
+static int ph_SetupWindow(_THIS, int w, int h, int flags)
+{
+ PtArg_t args[32];
+ PhPoint_t pos = {0, 0};
+ PhDim_t* olddim;
+ PhDim_t dim = {w, h};
+ PhRect_t desktopextent;
+ int nargs = 0;
+ const char* windowpos;
+ const char* iscentered;
+ int x, y;
+
+ /* check if window size has been changed by Window Manager */
+ PtGetResource(window, Pt_ARG_DIM, &olddim, 0);
+ if ((olddim->w!=w) || (olddim->h!=h))
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_DIM, &dim, 0);
+ }
+
+ if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MOVE | Ph_WM_CLOSE | Ph_WM_MAX | Ph_WM_RESTORE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
+ PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_TRUE, Pt_RESIZE_XY_AS_REQUIRED);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
+ PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
+ }
+
+ if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN))
+ {
+ if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER);
+ }
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE |
+ Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
+ }
+
+ if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
+ PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS | Ph_WM_STATE_ISALTKEY);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_FFRONT | Ph_WM_CONSWITCH);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
+
+ if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
+ }
+ if (!currently_maximized)
+ {
+ windowpos = SDL_getenv("SDL_VIDEO_WINDOW_POS");
+ iscentered = SDL_getenv("SDL_VIDEO_CENTERED");
+
+ if ((iscentered) || ((windowpos) && (SDL_strcmp(windowpos, "center")==0)))
+ {
+ PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
+ if (desktop_mode.width>w)
+ {
+ pos.x = (desktop_mode.width - w)/2;
+ }
+ if (desktop_mode.height>h)
+ {
+ pos.y = (desktop_mode.height - h)/2;
+ }
+
+ pos.x+=desktopextent.ul.x;
+ pos.y+=desktopextent.ul.y;
+ PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
+ }
+ else
+ {
+ if (windowpos)
+ {
+ if (SDL_sscanf(windowpos, "%d,%d", &x, &y) == 2)
+ {
+ if ((x<desktop_mode.width) && (y<desktop_mode.height))
+ {
+ PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
+ pos.x=x+desktopextent.ul.x;
+ pos.y=y+desktopextent.ul.y;
+ }
+ PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
+ }
+ }
+ }
+ }
+
+ /* if window is maximized render it as maximized */
+ if (currently_maximized)
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISMAX);
+ }
+ else
+ {
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISMAX);
+ }
+
+ /* do not grab the keyboard by default */
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
+
+ /* bring the focus to the window */
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS);
+
+ /* allow to catch hide event */
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
+ PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
+ }
+
+ PtSetResources(window, nargs, args);
+ PtRealizeWidget(window);
+ PtWindowToFront(window);
+
+#if 0 /* FIXME */
+ PtGetResource(window, Pt_ARG_POS, &olddim, 0);
+ fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h);
+#endif
+
+ return 0;
+}
+
+static const struct ColourMasks* ph_GetColourMasks(int bpp)
+{
+ /* The alpha mask doesn't appears to be needed */
+ static const struct ColourMasks phColorMasks[5] = {
+ /* 8 bit */ {0, 0, 0, 0, 8},
+ /* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 15},
+ /* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16},
+ /* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
+ /* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
+ };
+
+ switch (bpp)
+ {
+ case 8:
+ return &phColorMasks[0];
+ case 15:
+ return &phColorMasks[1];
+ case 16:
+ return &phColorMasks[2];
+ case 24:
+ return &phColorMasks[3];
+ case 32:
+ return &phColorMasks[4];
+ }
+ return NULL;
+}
+
+static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat)
+{
+ PgHWCaps_t hwcaps;
+ int i;
+
+ window=NULL;
+ desktoppal=SDLPH_PAL_NONE;
+
+#if SDL_VIDEO_OPENGL
+ oglctx=NULL;
+ oglbuffers=NULL;
+ oglflags=0;
+ oglbpp=0;
+#endif
+
+ old_video_mode=-1;
+ old_refresh_rate=-1;
+
+ if (NULL == (phevent = SDL_malloc(EVENT_SIZE)))
+ {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ SDL_memset(phevent, 0x00, EVENT_SIZE);
+
+ window = ph_CreateWindow(this);
+ if (window == NULL)
+ {
+ SDL_SetError("ph_VideoInit(): Couldn't create video window !\n");
+ return -1;
+ }
+
+ /* Create the blank cursor */
+ SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
+ (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
+ (int)BLANK_CHOTX, (int)BLANK_CHOTY);
+
+ if (SDL_BlankCursor == NULL)
+ {
+ return -1;
+ }
+
+ if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+ {
+ SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
+ this->FreeWMCursor(this, SDL_BlankCursor);
+ return -1;
+ }
+
+ if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0)
+ {
+ SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
+ this->FreeWMCursor(this, SDL_BlankCursor);
+ return -1;
+ }
+
+ /* Determine the current screen size */
+ this->info.current_w = desktop_mode.width;
+ this->info.current_h = desktop_mode.height;
+
+ /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
+ vformat->BitsPerPixel = desktop_mode.bits_per_pixel;
+ vformat->BytesPerPixel = desktop_mode.bytes_per_scanline/desktop_mode.width;
+ desktopbpp = desktop_mode.bits_per_pixel;
+
+ /* save current palette */
+ if (desktopbpp==8)
+ {
+ PgGetPalette(savedpal);
+ PgGetPalette(syspalph);
+ }
+ else
+ {
+ for(i=0; i<_Pg_MAX_PALETTE; i++)
+ {
+ savedpal[i]=PgRGB(0, 0, 0);
+ syspalph[i]=PgRGB(0, 0, 0);
+ }
+ }
+
+ currently_fullscreen = 0;
+ currently_hided = 0;
+ currently_maximized = 0;
+ current_overlay = NULL;
+
+ OCImage.direct_context = NULL;
+ OCImage.offscreen_context = NULL;
+ OCImage.offscreen_backcontext = NULL;
+ OCImage.oldDC = NULL;
+ OCImage.CurrentFrameData = NULL;
+ OCImage.FrameData0 = NULL;
+ OCImage.FrameData1 = NULL;
+ videomode_emulatemode = 0;
+
+ this->info.wm_available = 1;
+
+ ph_UpdateHWInfo(this);
+
+ return 0;
+}
+
+static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
+{
+ const struct ColourMasks* mask;
+
+ /* Lock the event thread, in multi-threading environments */
+ SDL_Lock_EventThread();
+
+ current->flags = flags;
+
+ /* if we do not have desired fullscreen mode, then fallback into window mode */
+ if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0))
+ {
+ current->flags &= ~SDL_FULLSCREEN;
+ current->flags &= ~SDL_NOFRAME;
+ current->flags &= ~SDL_RESIZABLE;
+ }
+
+ ph_SetupWindow(this, width, height, current->flags);
+
+ mask = ph_GetColourMasks(bpp);
+ if (mask != NULL)
+ {
+ SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0);
+ }
+ else
+ {
+ SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n");
+ return NULL;
+ }
+
+ if ((current->flags & SDL_OPENGL)==SDL_OPENGL)
+ {
+#if !SDL_VIDEO_OPENGL
+ /* if no built-in OpenGL support */
+ SDL_SetError("ph_SetVideoMode(): no OpenGL support, you need to recompile SDL.\n");
+ current->flags &= ~SDL_OPENGL;
+ return NULL;
+#endif /* SDL_VIDEO_OPENGL */
+ }
+ else
+ {
+ /* Initialize internal variables */
+ if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+ {
+ if (bpp==8)
+ {
+ desktoppal=SDLPH_PAL_SYSTEM;
+ }
+
+ current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */
+ current->flags |= SDL_HWSURFACE;
+ }
+ else
+ {
+ /* remove this if we'll have support for the non-fullscreen sw/hw+doublebuf one day */
+ current->flags &= ~SDL_DOUBLEBUF;
+
+ /* Use offscreen memory if SDL_HWSURFACE flag is set */
+ if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
+ {
+ if (desktopbpp!=bpp)
+ {
+ current->flags &= ~SDL_HWSURFACE;
+ }
+ }
+
+ /* using palette emulation code in window mode */
+ if (bpp==8)
+ {
+ if (desktopbpp>=15)
+ {
+ desktoppal = SDLPH_PAL_EMULATE;
+ }
+ else
+ {
+ desktoppal = SDLPH_PAL_SYSTEM;
+ }
+ }
+ else
+ {
+ desktoppal = SDLPH_PAL_NONE;
+ }
+ }
+ }
+
+ current->w = width;
+ current->h = height;
+
+ if (desktoppal==SDLPH_PAL_SYSTEM)
+ {
+ current->flags|=SDL_HWPALETTE;
+ }
+
+ /* Must call at least once for setup image planes */
+ if (ph_SetupUpdateFunction(this, current, current->flags)==-1)
+ {
+ /* Error string was filled in the ph_SetupUpdateFunction() */
+ return NULL;
+ }
+
+ /* finish window drawing, if we are not in fullscreen, of course */
+ if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
+ {
+ PtFlush();
+ }
+ else
+ {
+ PgFlush();
+ }
+
+ visualbpp=bpp;
+
+ ph_UpdateHWInfo(this);
+
+ SDL_Unlock_EventThread();
+
+ /* We've done! */
+ return (current);
+}
+
+static void ph_VideoQuit(_THIS)
+{
+ /* restore palette */
+ if (desktopbpp==8)
+ {
+ PgSetPalette(syspalph, 0, -1, 0, 0, 0);
+ PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
+ PgFlush();
+ }
+
+ ph_DestroyImage(this, SDL_VideoSurface);
+
+ if (window)
+ {
+ PtUnrealizeWidget(window);
+ PtDestroyWidget(window);
+ window=NULL;
+ }
+
+ if (phevent!=NULL)
+ {
+ SDL_free(phevent);
+ phevent=NULL;
+ }
+}
+
+static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ SDL_Rect updaterect;
+
+ updaterect.x = updaterect.y = 0;
+ updaterect.w = this->screen->w;
+ updaterect.h = this->screen->h;
+
+ /* palette emulation code, using palette of the PhImage_t struct */
+ if (desktoppal==SDLPH_PAL_EMULATE)
+ {
+ if ((SDL_Image) && (SDL_Image->palette))
+ {
+ for (i=firstcolor; i<firstcolor+ncolors; i++)
+ {
+ syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
+ SDL_Image->palette[i] = syspalph[i];
+ }
+
+ /* image needs to be redrawn */
+ this->UpdateRects(this, 1, &updaterect);
+ }
+ }
+ else
+ {
+ if (desktoppal==SDLPH_PAL_SYSTEM)
+ {
+ for (i=firstcolor; i<firstcolor+ncolors; i++)
+ {
+ syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
+ }
+
+ if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
+ {
+ /* window mode must use soft palette */
+ PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
+ /* image needs to be redrawn */
+ this->UpdateRects(this, 1, &updaterect);
+ }
+ else
+ {
+ /* fullscreen mode must use hardware palette */
+ PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
+ }
+ }
+ else
+ {
+ /* SDLPH_PAL_NONE do nothing */
+ }
+ }
+
+ return 1;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.h
new file mode 100644
index 0000000..3995d35
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_video.h
@@ -0,0 +1,157 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_VIDEO_H__
+#define __SDL_PH_VIDEO_H__
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+#include <sys/neutrino.h>
+
+#include <Ph.h>
+#include <Pt.h>
+#include <photon/Pg.h>
+#include <photon/PdDirect.h>
+
+#if SDL_VIDEO_OPENGL
+ #if (_NTO_VERSION < 630)
+ #include <photon/PdGL.h>
+ #else
+ #include <GL/qnxgl.h>
+ #include <GL/GLPh.h>
+ #endif /* 6.3.0 */
+#endif /* SDL_VIDEO_OPENGL */
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice* this
+
+#define PH_OGL_MAX_ATTRIBS 32
+
+#define SDLPH_PAL_NONE 0x00000000L
+#define SDLPH_PAL_EMULATE 0x00000001L
+#define SDLPH_PAL_SYSTEM 0x00000002L
+
+typedef struct
+{
+ unsigned char* Y;
+ unsigned char* V;
+ unsigned char* U;
+} FRAMEDATA;
+
+/* Mask values for SDL_ReallocFormat() */
+struct ColourMasks
+{
+ Uint32 red;
+ Uint32 green;
+ Uint32 blue;
+ Uint32 alpha;
+ Uint32 bpp;
+};
+
+/* Private display data */
+struct SDL_PrivateVideoData
+{
+ PgDisplaySettings_t mode_settings;
+ PtWidget_t *Window; /* used to handle input events */
+ PhImage_t *image; /* used to display image */
+#if SDL_VIDEO_OPENGL
+ #if (_NTO_VERSION < 630)
+ PdOpenGLContext_t* OGLContext; /* OpenGL context */
+ void* OGLBuffers; /* OpenGL buffers (unused) */
+ #else
+ qnxglc_t* OGLContext; /* OpenGL context for the 6.3 */
+ qnxgl_bufs_t* OGLBuffers; /* OpenGL buffers for the 6.3 */
+ #endif /* 630 */
+
+ Uint32 OGLFlags; /* OpenGL flags */
+ Uint32 OGLBPP; /* OpenGL bpp */
+#endif /* SDL_VIDEO_OPENGL */
+ PgColor_t savedpal[_Pg_MAX_PALETTE];
+ PgColor_t syspalph[_Pg_MAX_PALETTE];
+
+ struct
+ {
+ PdDirectContext_t* direct_context;
+ PdOffscreenContext_t* offscreen_context;
+ PdOffscreenContext_t* offscreen_backcontext;
+ PhDrawContext_t* oldDC;
+ uint8_t* dc_ptr;
+ unsigned char* CurrentFrameData;
+ unsigned char* FrameData0;
+ unsigned char* FrameData1;
+ Uint32 current;
+ Uint32 flags;
+ } ocimage;
+
+ PgHWCaps_t graphics_card_caps; /* Graphics card caps at the moment of start */
+ PgVideoModeInfo_t desktop_mode; /* Current desktop video mode information */
+ int old_video_mode; /* Stored mode before fullscreen switch */
+ int old_refresh_rate; /* Stored refresh rate befor fullscreen switch */
+
+ int mouse_relative;
+ WMcursor* BlankCursor;
+ uint32_t videomode_emulatemode;
+
+ Uint32 visualbpp; /* current visual bpp */
+ Uint32 desktopbpp; /* bpp of desktop at the moment of start */
+ Uint32 desktoppal; /* palette mode emulation or system */
+
+ int currently_fullscreen;
+ int currently_hided; /* 1 - window hided (minimazed), 0 - normal */
+ int currently_maximized; /* 1 - window hided (minimazed), 0 - normal */
+
+ PhEvent_t* event;
+ SDL_Overlay* overlay;
+};
+
+#define mode_settings (this->hidden->mode_settings)
+#define window (this->hidden->Window)
+#define SDL_Image (this->hidden->image)
+#define OCImage (this->hidden->ocimage)
+#define old_video_mode (this->hidden->old_video_mode)
+#define old_refresh_rate (this->hidden->old_refresh_rate)
+#define graphics_card_caps (this->hidden->graphics_card_caps)
+#define desktopbpp (this->hidden->desktopbpp)
+#define visualbpp (this->hidden->visualbpp)
+#define desktoppal (this->hidden->desktoppal)
+#define savedpal (this->hidden->savedpal)
+#define syspalph (this->hidden->syspalph)
+#define currently_fullscreen (this->hidden->currently_fullscreen)
+#define currently_hided (this->hidden->currently_hided)
+#define currently_maximized (this->hidden->currently_maximized)
+#define phevent (this->hidden->event)
+#define current_overlay (this->hidden->overlay)
+#define desktop_mode (this->hidden->desktop_mode)
+#define mouse_relative (this->hidden->mouse_relative)
+#define SDL_BlankCursor (this->hidden->BlankCursor)
+#define videomode_emulatemode (this->hidden->videomode_emulatemode)
+
+#if SDL_VIDEO_OPENGL
+ #define oglctx (this->hidden->OGLContext)
+ #define oglbuffers (this->hidden->OGLBuffers)
+ #define oglflags (this->hidden->OGLFlags)
+ #define oglbpp (this->hidden->OGLBPP)
+#endif /* SDL_VIDEO_OPENGL */
+
+#endif /* __SDL_PH_VIDEO_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm.c b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm.c
new file mode 100644
index 0000000..8e75d0b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm.c
@@ -0,0 +1,118 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <Ph.h>
+#include <photon/PpProto.h>
+#include <photon/PhWm.h>
+#include <photon/wmapi.h>
+
+#include "SDL_version.h"
+#include "SDL_timer.h"
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ph_modes_c.h"
+#include "SDL_ph_wm_c.h"
+
+void ph_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
+{
+ return;
+}
+
+/* Set window caption */
+void ph_SetCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_Lock_EventThread();
+
+ /* sanity check for set caption call before window init */
+ if (window!=NULL)
+ {
+ PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0);
+ }
+
+ SDL_Unlock_EventThread();
+}
+
+/* Iconify current window */
+int ph_IconifyWindow(_THIS)
+{
+ PhWindowEvent_t windowevent;
+
+ SDL_Lock_EventThread();
+
+ SDL_memset(&windowevent, 0, sizeof(windowevent));
+ windowevent.event_f = Ph_WM_HIDE;
+ windowevent.event_state = Ph_WM_EVSTATE_HIDE;
+ windowevent.rid = PtWidgetRid(window);
+ PtForwardWindowEvent(&windowevent);
+
+ SDL_Unlock_EventThread();
+
+ return 0;
+}
+
+SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
+{
+ short abs_x, abs_y;
+
+ if( mode == SDL_GRAB_OFF )
+ {
+ PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
+ }
+ else
+ {
+ PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
+
+ PtGetAbsPosition(window, &abs_x, &abs_y);
+ PhMoveCursorAbs(PhInputGroup(NULL), abs_x + SDL_VideoSurface->w/2, abs_y + SDL_VideoSurface->h/2);
+ }
+
+ SDL_Unlock_EventThread();
+
+ return(mode);
+}
+
+SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ SDL_Lock_EventThread();
+ mode = ph_GrabInputNoLock(this, mode);
+ SDL_Unlock_EventThread();
+
+ return(mode);
+}
+
+
+int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
+{
+ if (info->version.major <= SDL_MAJOR_VERSION)
+ {
+ return 1;
+ }
+ else
+ {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return -1;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm_c.h
new file mode 100644
index 0000000..72bbfd2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_ph_wm_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_WM_H__
+#define __SDL_PH_WM_H__
+
+#include "SDL_ph_video.h"
+
+/* Functions to be exported */
+extern void ph_SetCaption(_THIS, const char *title, const char *icon);
+extern void ph_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask);
+extern int ph_IconifyWindow(_THIS);
+extern SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode);
+extern SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode);
+extern int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info);
+
+#endif /* __SDL_PH_WM_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv.c b/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv.c
new file mode 100644
index 0000000..06c72fd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv.c
@@ -0,0 +1,504 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the QNX Realtime Platform version of SDL YUV video overlays */
+
+#include <errno.h>
+
+#include <Ph.h>
+#include <Pt.h>
+
+#include "SDL_video.h"
+#include "SDL_phyuv_c.h"
+#include "../SDL_yuvfuncs.h"
+
+#define OVERLAY_STATE_UNINIT 0
+#define OVERLAY_STATE_ACTIVE 1
+
+/* The functions are used to manipulate software video overlays */
+static struct private_yuvhwfuncs ph_yuvfuncs =
+{
+ ph_LockYUVOverlay,
+ ph_UnlockYUVOverlay,
+ ph_DisplayYUVOverlay,
+ ph_FreeYUVOverlay
+};
+
+int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1)
+{
+ int planes = 0;
+
+ /* Buffers have moved; re-obtain the pointers */
+ Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1);
+ Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
+ Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
+ Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
+ Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
+ Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
+
+ if (Frame0->Y)
+ planes++;
+
+ if (Frame0->U)
+ planes++;
+
+ if (Frame0->V)
+ planes++;
+
+ return planes;
+}
+
+SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display)
+{
+ SDL_Overlay* overlay;
+ struct private_yuvhwdata* hwdata;
+ int vidport;
+ int rtncode;
+ int planes;
+ int i=0;
+ PhPoint_t pos;
+
+ /* Create the overlay structure */
+ overlay = SDL_calloc(1, sizeof(SDL_Overlay));
+
+ if (overlay == NULL)
+ {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+ overlay->hwdata = NULL;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &ph_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
+
+ if (hwdata == NULL)
+ {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+
+ overlay->hwdata = hwdata;
+
+ PhDCSetCurrent(0);
+ if (overlay->hwdata->channel == NULL)
+ {
+ if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER, 0)) == NULL)
+ {
+ SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+
+ }
+ }
+
+ overlay->hwdata->forcedredraw=0;
+
+ PtGetAbsPosition(window, &pos.x, &pos.y);
+ overlay->hwdata->CurrentWindowPos.x = pos.x;
+ overlay->hwdata->CurrentWindowPos.y = pos.y;
+ overlay->hwdata->CurrentViewPort.pos.x = 0;
+ overlay->hwdata->CurrentViewPort.pos.y = 0;
+ overlay->hwdata->CurrentViewPort.size.w = width;
+ overlay->hwdata->CurrentViewPort.size.h = height;
+ overlay->hwdata->State = OVERLAY_STATE_UNINIT;
+ overlay->hwdata->FrameData0 = (FRAMEDATA *) SDL_calloc(1, sizeof(FRAMEDATA));
+ overlay->hwdata->FrameData1 = (FRAMEDATA *) SDL_calloc(1, sizeof(FRAMEDATA));
+
+ vidport = -1;
+ i=0;
+
+ overlay->hwdata->ischromakey=0;
+
+ do {
+ SDL_memset(&overlay->hwdata->caps, 0x00, sizeof(PgScalerCaps_t));
+ overlay->hwdata->caps.size = sizeof(PgScalerCaps_t);
+ rtncode = PgGetScalerCapabilities(overlay->hwdata->channel, i, &overlay->hwdata->caps);
+ if (rtncode==0)
+ {
+ if (overlay->hwdata->caps.format==format)
+ {
+ if ((overlay->hwdata->caps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY) == Pg_SCALER_CAP_DST_CHROMA_KEY)
+ {
+ overlay->hwdata->ischromakey=1;
+ }
+ vidport=1;
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ i++;
+ } while(1);
+
+
+ if (vidport == -1)
+ {
+ SDL_SetError("No available video ports for requested format\n");
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+
+ overlay->hwdata->format = format;
+ overlay->hwdata->props.format = format;
+ overlay->hwdata->props.size = sizeof(PgScalerProps_t);
+ overlay->hwdata->props.src_dim.w = width;
+ overlay->hwdata->props.src_dim.h = height;
+
+ /* overlay->hwdata->chromakey = PgGetOverlayChromaColor(); */
+ overlay->hwdata->chromakey = PgRGB(12, 6, 12); /* very dark pink color */
+ overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
+
+ PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport);
+
+ overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;
+
+ if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
+ {
+ overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
+ overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_SPECIFY_KEY_MASK;
+ }
+ else
+ {
+ overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
+ }
+
+ rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &overlay->hwdata->props);
+
+ switch(rtncode)
+ {
+ case -1: SDL_SetError("PgConfigScalerChannel failed\n");
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ case 1:
+ case 0:
+ default:
+ break;
+ }
+
+ planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
+
+ if(overlay->hwdata->channel->yplane1 != NULL)
+ overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
+ if(overlay->hwdata->channel->vplane1 != NULL)
+ overlay->hwdata->UStride = overlay->hwdata->channel->vplane1->pitch;
+ if(overlay->hwdata->channel->uplane1 != NULL)
+ overlay->hwdata->VStride = overlay->hwdata->channel->uplane1->pitch;
+
+ /* check for the validness of all planes */
+ if ((overlay->hwdata->channel->yplane1 == NULL) &&
+ (overlay->hwdata->channel->uplane1 == NULL) &&
+ (overlay->hwdata->channel->vplane1 == NULL))
+ {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_SetError("PgConfigScaler() returns all planes equal NULL\n");
+ return NULL;
+ }
+/*
+ overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+
+ if (overlay->hwdata->current==0)
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
+ else
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
+*/
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+
+/*
+ overlay->hwdata->locked = 1;
+*/
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->planes = planes;
+ overlay->pitches = SDL_calloc(overlay->planes, sizeof(Uint16));
+ overlay->pixels = SDL_calloc(overlay->planes, sizeof(Uint8*));
+ if (!overlay->pitches || !overlay->pixels)
+ {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+
+ if (overlay->planes > 0)
+ {
+ overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+ overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
+ }
+ if (overlay->planes > 1)
+ {
+ overlay->pitches[1] = overlay->hwdata->channel->vplane1->pitch;
+ overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
+ }
+ if (overlay->planes > 2)
+ {
+ overlay->pitches[2] = overlay->hwdata->channel->uplane1->pitch;
+ overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
+ }
+
+ overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
+ overlay->hwdata->scaler_on = 0;
+ overlay->hw_overlay = 1;
+
+ current_overlay=overlay;
+
+ return overlay;
+}
+
+int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay)
+{
+ if (overlay == NULL)
+ {
+ return -1;
+ }
+
+ overlay->hwdata->locked = 1;
+
+/* overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+ if (overlay->hwdata->current == -1)
+ {
+ SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n");
+ SDL_FreeYUVOverlay(overlay);
+ return 0;
+ }
+
+ if (overlay->hwdata->current == 0)
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
+ else
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
+
+ if (overlay->planes > 0)
+ {
+ overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+ overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
+ }
+ if (overlay->planes > 1)
+ {
+ overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
+ overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
+ }
+ if (overlay->planes > 2)
+ {
+ overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
+ overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
+ }
+*/
+
+ return(0);
+}
+
+void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay)
+{
+ if (overlay == NULL)
+ {
+ return;
+ }
+
+ overlay->hwdata->locked = 0;
+}
+
+int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect* dst)
+{
+ int rtncode;
+ PhPoint_t pos;
+ SDL_Rect backrect;
+ PhRect_t windowextent;
+ int winchanged=0;
+
+ if ((overlay == NULL) || (overlay->hwdata==NULL))
+ {
+ return -1;
+ }
+
+ if (overlay->hwdata->State == OVERLAY_STATE_UNINIT)
+ {
+ return -1;
+ }
+
+ PtGetAbsPosition(window, &pos.x, &pos.y);
+ if ((pos.x!=overlay->hwdata->CurrentWindowPos.x) ||
+ (pos.y!=overlay->hwdata->CurrentWindowPos.y))
+ {
+ winchanged=1;
+ overlay->hwdata->CurrentWindowPos.x=pos.x;
+ overlay->hwdata->CurrentWindowPos.y=pos.y;
+ }
+
+ /* If CurrentViewPort position/size has been changed, then move/resize the viewport */
+ if ((overlay->hwdata->CurrentViewPort.pos.x != dst->x) ||
+ (overlay->hwdata->CurrentViewPort.pos.y != dst->y) ||
+ (overlay->hwdata->CurrentViewPort.size.w != dst->w) ||
+ (overlay->hwdata->CurrentViewPort.size.h != dst->h) ||
+ (overlay->hwdata->scaler_on==0) || (winchanged==1) ||
+ (overlay->hwdata->forcedredraw==1))
+ {
+
+ if (overlay->hwdata->ischromakey==1)
+ {
+ /* restore screen behind the overlay/chroma color. */
+ backrect.x=overlay->hwdata->CurrentViewPort.pos.x;
+ backrect.y=overlay->hwdata->CurrentViewPort.pos.y;
+ backrect.w=overlay->hwdata->CurrentViewPort.size.w;
+ backrect.h=overlay->hwdata->CurrentViewPort.size.h;
+ this->UpdateRects(this, 1, &backrect);
+
+ /* Draw the new rectangle of the chroma color at the viewport position */
+ PgSetFillColor(overlay->hwdata->chromakey);
+ PgDrawIRect(dst->x, dst->y, dst->x+dst->w-1, dst->y+dst->h-1, Pg_DRAW_FILL);
+ PgFlush();
+ }
+
+ overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
+ overlay->hwdata->scaler_on = 1;
+
+ PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, PtWidgetRid(window), &windowextent);
+ overlay->hwdata->CurrentViewPort.pos.x = pos.x-windowextent.ul.x+dst->x;
+ overlay->hwdata->CurrentViewPort.pos.y = pos.y-windowextent.ul.y+dst->y;
+ overlay->hwdata->CurrentViewPort.size.w = dst->w;
+ overlay->hwdata->CurrentViewPort.size.h = dst->h;
+ PhAreaToRect(&overlay->hwdata->CurrentViewPort, &overlay->hwdata->props.viewport);
+ overlay->hwdata->CurrentViewPort.pos.x = dst->x;
+ overlay->hwdata->CurrentViewPort.pos.y = dst->y;
+
+ rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
+
+ switch(rtncode)
+ {
+ case -1:
+ SDL_SetError("PgConfigScalerChannel() function failed\n");
+ SDL_FreeYUVOverlay(overlay);
+ return -1;
+ case 1:
+ grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
+ break;
+ case 0:
+ default:
+ break;
+ }
+ }
+
+
+/*
+ if (overlay->hwdata->locked==0)
+ {
+ overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
+ if (overlay->hwdata->current == -1)
+ {
+ SDL_SetError("ph_LockYUVOverlay: PgNextFrame() failed, bailing out\n");
+ SDL_FreeYUVOverlay(overlay);
+ return 0;
+ }
+
+ if (overlay->hwdata->current == 0)
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
+ }
+ else
+ {
+ overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
+ }
+
+ if (overlay->planes > 0)
+ {
+ overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
+ overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
+ }
+ if (overlay->planes > 1)
+ {
+ overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
+ overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
+ }
+ if (overlay->planes > 2)
+ {
+ overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
+ overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
+ }
+ }
+*/
+
+ return 0;
+}
+
+void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ SDL_Rect backrect;
+
+ if (overlay == NULL)
+ {
+ return;
+ }
+
+ if (overlay->hwdata == NULL)
+ {
+ return;
+ }
+
+ current_overlay=NULL;
+
+ /* restore screen behind the overlay/chroma color. */
+ backrect.x=overlay->hwdata->CurrentViewPort.pos.x;
+ backrect.y=overlay->hwdata->CurrentViewPort.pos.y;
+ backrect.w=overlay->hwdata->CurrentViewPort.size.w;
+ backrect.h=overlay->hwdata->CurrentViewPort.size.h;
+ this->UpdateRects(this, 1, &backrect);
+
+ /* it is need for some buggy drivers, that can't hide overlay before */
+ /* freeing buffer, so we got trash on the srceen */
+ overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_SCALER_ENABLE;
+ PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
+
+ overlay->hwdata->scaler_on = 0;
+ overlay->hwdata->State = OVERLAY_STATE_UNINIT;
+
+ if (overlay->hwdata->channel != NULL)
+ {
+ PgDestroyVideoChannel(overlay->hwdata->channel);
+ overlay->hwdata->channel = NULL;
+ return;
+ }
+
+ overlay->hwdata->CurrentFrameData = NULL;
+
+ SDL_free(overlay->hwdata->FrameData0);
+ SDL_free(overlay->hwdata->FrameData1);
+ overlay->hwdata->FrameData0 = NULL;
+ overlay->hwdata->FrameData1 = NULL;
+ SDL_free(overlay->hwdata);
+}
diff --git a/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv_c.h b/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv_c.h
new file mode 100644
index 0000000..c6f73fe
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/photon/SDL_phyuv_c.h
@@ -0,0 +1,62 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_PH_YUV_H__
+#define __SDL_PH_YUV_H__
+
+/* This is the photon implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_ph_video.h"
+
+struct private_yuvhwdata
+{
+ FRAMEDATA* CurrentFrameData;
+ FRAMEDATA* FrameData0;
+ FRAMEDATA* FrameData1;
+ PgScalerProps_t props;
+ PgScalerCaps_t caps;
+ PgVideoChannel_t* channel;
+ PhArea_t CurrentViewPort;
+ PhPoint_t CurrentWindowPos;
+ long format;
+ int scaler_on;
+ int current;
+ long YStride;
+ long VStride;
+ long UStride;
+ int ischromakey;
+ long chromakey;
+ int forcedredraw;
+ unsigned long State;
+ long flags;
+ int locked;
+};
+
+extern SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface* display);
+extern int ph_LockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay* overlay);
+extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay* overlay, SDL_Rect* src, SDL_Rect* dst);
+extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay* overlay);
+
+#endif /* __SDL_PH_YUV_H__ */
diff --git a/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents.c b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents.c
new file mode 100644
index 0000000..5006c07
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents.c
@@ -0,0 +1,117 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+
+ Micah Dowty
+ micahjd@users.sourceforge.net
+*/
+#include "SDL_config.h"
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_pgvideo.h"
+#include "SDL_pgevents_c.h"
+
+int PG_HandleClose(struct pgEvent *evt)
+{
+ SDL_PrivateQuit();
+ return 1; /* Intercept the event's normal quit handling */
+}
+
+int PG_HandleResize(struct pgEvent *evt)
+{
+ SDL_PrivateResize(evt->e.size.w, evt->e.size.h);
+ return 0;
+}
+
+int PG_HandleKey(struct pgEvent *evt)
+{
+ SDL_keysym sym;
+ SDL_memset(&sym,0,sizeof(sym));
+ sym.sym = evt->e.kbd.key;
+ sym.mod = evt->e.kbd.mods;
+ SDL_PrivateKeyboard(evt->type == PG_WE_KBD_KEYDOWN, &sym);
+ return 0;
+}
+
+int PG_HandleChar(struct pgEvent *evt)
+{
+ SDL_keysym sym;
+ SDL_memset(&sym,0,sizeof(sym));
+ sym.unicode = evt->e.kbd.key;
+ sym.mod = evt->e.kbd.mods;
+ SDL_PrivateKeyboard(evt->type == PG_WE_KBD_KEYDOWN, &sym);
+ return 0;
+}
+
+int PG_HandleMouseButton(struct pgEvent *evt)
+{
+ /* We need to focus the canvas when it's clicked */
+ if (evt->extra) {
+ SDL_VideoDevice *this = (SDL_VideoDevice *) evt->extra;
+ pgFocus(this->hidden->wCanvas);
+ }
+ SDL_PrivateMouseButton(evt->type == PG_WE_PNTR_DOWN, evt->e.pntr.chbtn,
+ evt->e.pntr.x, evt->e.pntr.y);
+ return 0;
+}
+
+int PG_HandleMouseMotion(struct pgEvent *evt)
+{
+ SDL_PrivateMouseMotion(evt->e.pntr.btn,0,evt->e.pntr.x, evt->e.pntr.y);
+ return 0;
+}
+
+void PG_PumpEvents(_THIS)
+{
+ /* Process all pending events */
+ pgEventPoll();
+}
+
+void PG_InitOSKeymap(_THIS)
+{
+ /* We need no keymap */
+}
+
+void PG_InitEvents(_THIS)
+{
+ /* Turn on all the mouse and keyboard triggers for our canvas, normally less important
+ * events like mouse movement are ignored to save bandwidth. */
+ pgSetWidget(this->hidden->wCanvas, PG_WP_TRIGGERMASK,
+ pgGetWidget(this->hidden->wCanvas, PG_WP_TRIGGERMASK) |
+ PG_TRIGGER_UP | PG_TRIGGER_DOWN | PG_TRIGGER_MOVE |
+ PG_TRIGGER_KEYUP | PG_TRIGGER_KEYDOWN | PG_TRIGGER_CHAR,0);
+
+ /* Start our canvas out focused, so we get keyboard input */
+ pgFocus(this->hidden->wCanvas);
+
+ /* Set up bindings for all the above event handlers */
+ pgBind(this->hidden->wApp, PG_WE_CLOSE, &PG_HandleClose, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_BUILD, &PG_HandleResize, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_KBD_CHAR, &PG_HandleChar, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_KBD_KEYUP, &PG_HandleKey, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_KBD_KEYDOWN, &PG_HandleKey, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_PNTR_MOVE, &PG_HandleMouseMotion, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_PNTR_UP, &PG_HandleMouseButton, NULL);
+ pgBind(this->hidden->wCanvas, PG_WE_PNTR_DOWN, &PG_HandleMouseButton, this);
+}
+
+/* end of SDL_pgevents.c ... */
diff --git a/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents_c.h b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents_c.h
new file mode 100644
index 0000000..a54e225
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgevents_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+
+ Micah Dowty
+ micahjd@users.sourceforge.net
+*/
+#include "SDL_config.h"
+
+#include "SDL_pgvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void PG_PumpEvents(_THIS);
+extern void PG_InitEvents(_THIS);
+extern void PG_InitOSKeymap(_THIS);
+
+/* end of SDL_pgevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.c b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.c
new file mode 100644
index 0000000..18b3fe4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.c
@@ -0,0 +1,364 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+
+ Micah Dowty
+ micahjd@users.sourceforge.net
+*/
+#include "SDL_config.h"
+
+#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_pgvideo.h"
+#include "SDL_pgevents_c.h"
+
+#define PGVID_DRIVER_NAME "picogui"
+
+/* Initialization/Query functions */
+static int PG_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **PG_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *PG_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int PG_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void PG_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int PG_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int PG_LockHWSurface(_THIS, SDL_Surface *surface);
+static void PG_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void PG_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* etc. */
+static void PG_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+// The implementation dependent data for the window manager cursor
+struct WMcursor {
+ /* Our cursor is a PicoGUI theme */
+ pghandle theme;
+} ;
+
+/* WM functions */
+void PG_SetCaption(_THIS, const char *title, const char *icon);
+WMcursor * PG_CreateWMCursor (_THIS,Uint8 * data, Uint8 * mask,
+ int w, int h, int hot_x, int hot_y);
+void PG_FreeWMCursor (_THIS, WMcursor * cursor);
+void PG_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+int PG_ShowWMCursor (_THIS, WMcursor * cursor);
+
+/* PicoGUI driver bootstrap functions */
+
+static int PG_Available(void)
+{
+ /* FIXME: The current client lib doesn't give a way to see if the picogui
+ * server is reachable without causing a fatal error if it isn't.
+ * This should be fixed in cli_c2, but until then assume we can
+ * connect. Since more common drivers like X11 are probed first anyway,
+ * this shouldn't be a huge problem.
+ */
+ return(1);
+}
+
+static void PG_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *PG_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = PG_VideoInit;
+ device->ListModes = PG_ListModes;
+ device->SetVideoMode = PG_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->SetColors = PG_SetColors;
+ device->UpdateRects = PG_UpdateRects;
+ device->VideoQuit = PG_VideoQuit;
+ device->AllocHWSurface = PG_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = PG_LockHWSurface;
+ device->UnlockHWSurface = PG_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = PG_FreeHWSurface;
+ device->SetCaption = PG_SetCaption;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+
+ device->PumpEvents = PG_PumpEvents;
+ device->InitOSKeymap = PG_InitOSKeymap;
+
+ device->ShowWMCursor = PG_ShowWMCursor;
+ device->CreateWMCursor = PG_CreateWMCursor;
+ device->FreeWMCursor = PG_FreeWMCursor;
+ device->WarpWMCursor = PG_WarpWMCursor;
+
+ device->free = PG_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap PG_bootstrap = {
+ PGVID_DRIVER_NAME, "PicoGUI SDL driver",
+ PG_Available, PG_CreateDevice
+};
+
+
+int PG_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ /* Connect to the PicoGUI server. No way to process command line args yet,
+ * but since this is based on SHM it's not important to be able to specify
+ * a remote PicoGUI server.
+ *
+ * FIXME: Another nitpick about the current client lib is there's no
+ * clean way to indicate that command line args are not available.
+ */
+ pgInit(0,(char**)"");
+ this->hidden->mi = *pgGetVideoMode();
+
+ /* Create a picogui application and canvas. We'll populate the canvas later. */
+ this->hidden->wApp = pgRegisterApp(PG_APP_NORMAL,"SDL",0);
+ this->hidden->wCanvas = pgNewWidget(PG_WIDGET_CANVAS,0,0);
+ pgSetWidget(PGDEFAULT,
+ PG_WP_SIDE, PG_S_ALL,
+ 0);
+
+ PG_InitEvents(this);
+
+ /* Determine the current screen size */
+ this->info.current_w = this->hidden->mi.lxres;
+ this->info.current_h = this->hidden->mi.lyres;
+
+ /* Determine the screen depth.
+ * We change this during the SDL_SetVideoMode implementation...
+ * Round up to the nearest Bytes per pixel
+ */
+ vformat->BitsPerPixel = this->hidden->mi.bpp;
+ vformat->BytesPerPixel = this->hidden->mi.bpp >> 3;
+ if (this->hidden->mi.bpp & 7)
+ vformat->BytesPerPixel++;
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **PG_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return (SDL_Rect **) -1;
+}
+
+SDL_Surface *PG_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if ( this->hidden->bitmap ) {
+ /* Free old bitmap */
+ if (current->pixels) {
+ shmdt(current->pixels);
+ current->pixels = NULL;
+ }
+ pgDelete(this->hidden->bitmap);
+ }
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Create a new picogui bitmap */
+ this->hidden->bitmap = pgCreateBitmap(width,height);
+ this->hidden->shm = *pgMakeSHMBitmap(this->hidden->bitmap);
+ current->pixels = shmat(shmget(this->hidden->shm.shm_key,
+ this->hidden->shm.shm_length,0),NULL,0);
+
+ /* Reset the canvas, and draw persistent and incremental grops.
+ * Use mapping and offsets to center it.
+ */
+
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_NUKE, 0);
+
+ /* 0. Set the source position during incremental rendering
+ */
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 5, PG_GROP_SETSRC,0,0,0,0);
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL);
+
+ /* 1. Incremental bitmap rendering
+ */
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP,
+ 0,0,0,0,this->hidden->bitmap);
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL);
+
+ /* 2. Normal bitmap rendering
+ */
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP,
+ 0,0,this->hidden->shm.width,this->hidden->shm.height,this->hidden->bitmap);
+
+ /* Set up the new mode framebuffer */
+ current->flags = 0;
+ current->w = this->hidden->shm.width;
+ current->h = this->hidden->shm.height;
+ current->pitch = this->hidden->shm.pitch;
+
+ /* Set up pixel format */
+ current->format->BitsPerPixel = this->hidden->shm.bpp;
+ current->format->BytesPerPixel = this->hidden->shm.bpp >> 3;
+ if (this->hidden->shm.bpp & 7)
+ current->format->BytesPerPixel++;
+ current->format->palette = NULL;
+ current->format->Rmask = this->hidden->shm.red_mask;
+ current->format->Gmask = this->hidden->shm.green_mask;
+ current->format->Bmask = this->hidden->shm.blue_mask;
+ current->format->Amask = this->hidden->shm.alpha_mask;
+ current->format->Rshift = this->hidden->shm.red_shift;
+ current->format->Gshift = this->hidden->shm.green_shift;
+ current->format->Bshift = this->hidden->shm.blue_shift;
+ current->format->Ashift = this->hidden->shm.alpha_shift;
+ current->format->Rloss = 8 - this->hidden->shm.red_length;
+ current->format->Gloss = 8 - this->hidden->shm.green_length;
+ current->format->Bloss = 8 - this->hidden->shm.blue_length;
+ current->format->Aloss = 8 - this->hidden->shm.alpha_length;
+
+ /* Draw the app */
+ pgUpdate();
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int PG_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void PG_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int PG_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void PG_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void PG_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i;
+
+ for (i = 0; i < numrects; i++) {
+ if (rects[i].w <= 0 || rects[i].h <= 0)
+ continue;
+
+ /* Schedule an incremental update for this rectangle, using
+ * the canvas gropnodes we've loaded beforehand.
+ */
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_FINDGROP, 1, 0);
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_MOVEGROP, 4,
+ rects[i].x, rects[i].y,
+ rects[i].w, rects[i].h);
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_FINDGROP, 1, 1);
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_MOVEGROP, 4,
+ rects[i].x, rects[i].y,
+ rects[i].w, rects[i].h);
+
+ /* Go perform the update */
+ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_INCREMENTAL, 0);
+ pgSubUpdate(this->hidden->wCanvas);
+ }
+}
+
+int PG_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ /* do nothing of note. */
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void PG_VideoQuit(_THIS)
+{
+ if (this->screen->pixels != NULL)
+ {
+ shmdt(this->screen->pixels);
+ this->screen->pixels = NULL;
+ pgDelete(this->hidden->bitmap);
+ }
+ pgDelete(this->hidden->wCanvas);
+ pgDelete(this->hidden->wApp);
+}
+
+void PG_SetCaption(_THIS, const char *title, const char *icon)
+{
+ if (title != NULL)
+ pgReplaceText(this->hidden->wApp, title);
+ pgUpdate();
+}
+
+/* FIXME: The cursor stuff isn't implemented yet! */
+
+WMcursor * PG_CreateWMCursor (_THIS,Uint8 * data, Uint8 * mask,
+ int w, int h, int hot_x, int hot_y)
+{
+ static WMcursor dummy;
+ return &dummy;
+}
+
+void PG_FreeWMCursor (_THIS, WMcursor * cursor)
+{
+}
+
+void PG_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+}
+
+int PG_ShowWMCursor (_THIS, WMcursor * cursor)
+{
+ return 1;
+}
diff --git a/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.h b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.h
new file mode 100644
index 0000000..155f86b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/picogui/SDL_pgvideo.h
@@ -0,0 +1,50 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+
+ Micah Dowty
+ micahjd@users.sourceforge.net
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_pgvideo_h
+#define _SDL_pgvideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+#include <picogui.h>
+#include <sys/shm.h>
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ pghandle wApp, wCanvas; /* PicoGUI widgets */
+ pghandle bitmap;
+ struct pgshmbitmap shm; /* shared memory info */
+ struct pgmodeinfo mi; /* PicoGUI video mode info structure */
+};
+
+#endif /* _SDL_pgvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents.c b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents.c
new file mode 100644
index 0000000..1b842af
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents.c
@@ -0,0 +1,977 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting console events into SDL events */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+/* For parsing /proc */
+#include <dirent.h>
+#include <ctype.h>
+
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_gsvideo.h"
+#include "SDL_gsevents_c.h"
+#include "SDL_gskeys.h"
+
+#ifndef GPM_NODE_FIFO
+#define GPM_NODE_FIFO "/dev/gpmdata"
+#endif
+
+/* The translation tables from a console scancode to a SDL keysym */
+#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
+static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS];
+static SDLKey keymap[128];
+static Uint16 keymap_temp[128]; /* only used at startup */
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
+
+/* Ugh, we have to duplicate the kernel's keysym mapping code...
+ Oh, it's not so bad. :-)
+
+ FIXME: Add keyboard LED handling code
+ */
+static void GS_vgainitkeymaps(int fd)
+{
+ struct kbentry entry;
+ int map, i;
+
+ /* Don't do anything if we are passed a closed keyboard */
+ if ( fd < 0 ) {
+ return;
+ }
+
+ /* Load all the keysym mappings */
+ for ( map=0; map<NUM_VGAKEYMAPS; ++map ) {
+ SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16));
+ for ( i=0; i<NR_KEYS; ++i ) {
+ entry.kb_table = map;
+ entry.kb_index = i;
+ if ( ioctl(fd, KDGKBENT, &entry) == 0 ) {
+ /* fill keytemp. This replaces SDL_fbkeys.h */
+ if ( (map == 0) && (i<128) ) {
+ keymap_temp[i] = entry.kb_value;
+ }
+ /* The "Enter" key is a special case */
+ if ( entry.kb_value == K_ENTER ) {
+ entry.kb_value = K(KT_ASCII,13);
+ }
+ /* Handle numpad specially as well */
+ if ( KTYP(entry.kb_value) == KT_PAD ) {
+ switch ( entry.kb_value ) {
+ case K_P0:
+ case K_P1:
+ case K_P2:
+ case K_P3:
+ case K_P4:
+ case K_P5:
+ case K_P6:
+ case K_P7:
+ case K_P8:
+ case K_P9:
+ vga_keymap[map][i]=entry.kb_value;
+ vga_keymap[map][i]+= '0';
+ break;
+ case K_PPLUS:
+ vga_keymap[map][i]=K(KT_ASCII,'+');
+ break;
+ case K_PMINUS:
+ vga_keymap[map][i]=K(KT_ASCII,'-');
+ break;
+ case K_PSTAR:
+ vga_keymap[map][i]=K(KT_ASCII,'*');
+ break;
+ case K_PSLASH:
+ vga_keymap[map][i]=K(KT_ASCII,'/');
+ break;
+ case K_PENTER:
+ vga_keymap[map][i]=K(KT_ASCII,'\r');
+ break;
+ case K_PCOMMA:
+ vga_keymap[map][i]=K(KT_ASCII,',');
+ break;
+ case K_PDOT:
+ vga_keymap[map][i]=K(KT_ASCII,'.');
+ break;
+ default:
+ break;
+ }
+ }
+ /* Do the normal key translation */
+ if ( (KTYP(entry.kb_value) == KT_LATIN) ||
+ (KTYP(entry.kb_value) == KT_ASCII) ||
+ (KTYP(entry.kb_value) == KT_LETTER) ) {
+ vga_keymap[map][i] = entry.kb_value;
+ }
+ }
+ }
+ }
+}
+
+int GS_InGraphicsMode(_THIS)
+{
+ return((keyboard_fd >= 0) && (saved_kbd_mode >= 0));
+}
+
+int GS_EnterGraphicsMode(_THIS)
+{
+ struct termios keyboard_termios;
+
+ /* Set medium-raw keyboard mode */
+ if ( (keyboard_fd >= 0) && !GS_InGraphicsMode(this) ) {
+
+ /* Switch to the correct virtual terminal */
+ if ( current_vt > 0 ) {
+ struct vt_stat vtstate;
+
+ if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) {
+ saved_vt = vtstate.v_active;
+ }
+ if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) {
+ ioctl(keyboard_fd, VT_WAITACTIVE, current_vt);
+ }
+ }
+
+ /* Set the terminal input mode */
+ if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) {
+ SDL_SetError("Unable to get terminal attributes");
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ keyboard_fd = -1;
+ return(-1);
+ }
+ if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) {
+ SDL_SetError("Unable to get current keyboard mode");
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ keyboard_fd = -1;
+ return(-1);
+ }
+ keyboard_termios = saved_kbd_termios;
+ keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
+ keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
+ keyboard_termios.c_cc[VMIN] = 0;
+ keyboard_termios.c_cc[VTIME] = 0;
+ if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) {
+ GS_CloseKeyboard(this);
+ SDL_SetError("Unable to set terminal attributes");
+ return(-1);
+ }
+ /* This will fail if we aren't root or this isn't our tty */
+ if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) {
+ GS_CloseKeyboard(this);
+ SDL_SetError("Unable to set keyboard in raw mode");
+ return(-1);
+ }
+ if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) {
+ GS_CloseKeyboard(this);
+ SDL_SetError("Unable to set keyboard in graphics mode");
+ return(-1);
+ }
+ }
+ return(keyboard_fd);
+}
+
+void GS_LeaveGraphicsMode(_THIS)
+{
+ if ( GS_InGraphicsMode(this) ) {
+ ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
+ ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode);
+ tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios);
+ saved_kbd_mode = -1;
+
+ /* Head back over to the original virtual terminal */
+ if ( saved_vt > 0 ) {
+ ioctl(keyboard_fd, VT_ACTIVATE, saved_vt);
+ }
+ }
+}
+
+void GS_CloseKeyboard(_THIS)
+{
+ if ( keyboard_fd >= 0 ) {
+ GS_LeaveGraphicsMode(this);
+ if ( keyboard_fd > 0 ) {
+ close(keyboard_fd);
+ }
+ }
+ keyboard_fd = -1;
+}
+
+int GS_OpenKeyboard(_THIS)
+{
+ /* Open only if not already opened */
+ if ( keyboard_fd < 0 ) {
+ char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+ char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
+ int i, tty0_fd;
+
+ /* Try to query for a free virtual terminal */
+ tty0_fd = -1;
+ for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) {
+ tty0_fd = open(tty0[i], O_WRONLY, 0);
+ }
+ if ( tty0_fd < 0 ) {
+ tty0_fd = dup(0); /* Maybe stdin is a VT? */
+ }
+ ioctl(tty0_fd, VT_OPENQRY, &current_vt);
+ close(tty0_fd);
+ if ( (geteuid() == 0) && (current_vt > 0) ) {
+ for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) {
+ char vtpath[12];
+
+ SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt);
+ keyboard_fd = open(vtpath, O_RDWR, 0);
+#ifdef DEBUG_KEYBOARD
+ fprintf(stderr, "vtpath = %s, fd = %d\n",
+ vtpath, keyboard_fd);
+#endif /* DEBUG_KEYBOARD */
+
+ /* This needs to be our controlling tty
+ so that the kernel ioctl() calls work
+ */
+ if ( keyboard_fd >= 0 ) {
+ tty0_fd = open("/dev/tty", O_RDWR, 0);
+ if ( tty0_fd >= 0 ) {
+ ioctl(tty0_fd, TIOCNOTTY, 0);
+ close(tty0_fd);
+ }
+ }
+ }
+ }
+ if ( keyboard_fd < 0 ) {
+ /* Last resort, maybe our tty is a usable VT */
+ current_vt = 0;
+ keyboard_fd = open("/dev/tty", O_RDWR);
+ }
+#ifdef DEBUG_KEYBOARD
+ fprintf(stderr, "Current VT: %d\n", current_vt);
+#endif
+ saved_kbd_mode = -1;
+
+ /* Make sure that our input is a console terminal */
+ { int dummy;
+ if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) {
+ close(keyboard_fd);
+ keyboard_fd = -1;
+ SDL_SetError("Unable to open a console terminal");
+ }
+ }
+
+ /* Set up keymap */
+ GS_vgainitkeymaps(keyboard_fd);
+ }
+ return(keyboard_fd);
+}
+
+static enum {
+ MOUSE_NONE = -1,
+ MOUSE_GPM, /* Note: GPM uses the MSC protocol */
+ MOUSE_PS2,
+ MOUSE_IMPS2,
+ MOUSE_MS,
+ MOUSE_BM,
+ NUM_MOUSE_DRVS
+} mouse_drv = MOUSE_NONE;
+
+void GS_CloseMouse(_THIS)
+{
+ if ( mouse_fd > 0 ) {
+ close(mouse_fd);
+ }
+ mouse_fd = -1;
+}
+
+/* Returns processes listed in /proc with the desired name */
+static int find_pid(DIR *proc, const char *wanted_name)
+{
+ struct dirent *entry;
+ int pid;
+
+ /* First scan proc for the gpm process */
+ pid = 0;
+ while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) {
+ if ( isdigit(entry->d_name[0]) ) {
+ FILE *status;
+ char path[PATH_MAX];
+ char name[PATH_MAX];
+
+ SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name);
+ status=fopen(path, "r");
+ if ( status ) {
+ name[0] = '\0';
+ fscanf(status, "Name: %s", name);
+ if ( SDL_strcmp(name, wanted_name) == 0 ) {
+ pid = atoi(entry->d_name);
+ }
+ fclose(status);
+ }
+ }
+ }
+ return pid;
+}
+
+/* Returns true if /dev/gpmdata is being written to by gpm */
+static int gpm_available(void)
+{
+ int available;
+ DIR *proc;
+ int pid;
+ int cmdline, len, arglen;
+ char path[PATH_MAX];
+ char args[PATH_MAX], *arg;
+
+ /* Don't bother looking if the fifo isn't there */
+ if ( access(GPM_NODE_FIFO, F_OK) < 0 ) {
+ return(0);
+ }
+
+ available = 0;
+ proc = opendir("/proc");
+ if ( proc ) {
+ while ( (pid=find_pid(proc, "gpm")) > 0 ) {
+ SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid);
+ cmdline = open(path, O_RDONLY, 0);
+ if ( cmdline >= 0 ) {
+ len = read(cmdline, args, sizeof(args));
+ arg = args;
+ while ( len > 0 ) {
+ if ( SDL_strcmp(arg, "-R") == 0 ) {
+ available = 1;
+ }
+ arglen = SDL_strlen(arg)+1;
+ len -= arglen;
+ arg += arglen;
+ }
+ close(cmdline);
+ }
+ }
+ closedir(proc);
+ }
+ return available;
+}
+
+
+/* rcg06112001 Set up IMPS/2 mode, if possible. This gives
+ * us access to the mousewheel, etc. Returns zero if
+ * writes to device failed, but you still need to query the
+ * device to see which mode it's actually in.
+ */
+static int set_imps2_mode(int fd)
+{
+ /* If you wanted to control the mouse mode (and we do :) ) ...
+ Set IMPS/2 protocol:
+ {0xf3,200,0xf3,100,0xf3,80}
+ Reset mouse device:
+ {0xFF}
+ */
+ Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};
+ Uint8 reset = 0xff;
+ fd_set fdset;
+ struct timeval tv;
+ int retval = 0;
+
+ if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
+ if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
+ retval = 1;
+ }
+ }
+
+ /* Get rid of any chatter from the above */
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
+ char temp[32];
+ read(fd, temp, sizeof(temp));
+ }
+
+ return retval;
+}
+
+
+/* Returns true if the mouse uses the IMPS/2 protocol */
+static int detect_imps2(int fd)
+{
+ int imps2;
+
+ imps2 = 0;
+
+ if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) {
+ imps2 = 1;
+ }
+ if ( ! imps2 ) {
+ Uint8 query_ps2 = 0xF2;
+ fd_set fdset;
+ struct timeval tv;
+
+ /* Get rid of any mouse motion noise */
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
+ char temp[32];
+ read(fd, temp, sizeof(temp));
+ }
+
+ /* Query for the type of mouse protocol */
+ if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) {
+ Uint8 ch = 0;
+
+ /* Get the mouse protocol response */
+ do {
+ FD_ZERO(&fdset);
+ FD_SET(fd, &fdset);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) {
+ break;
+ }
+ } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) &&
+ ((ch == 0xFA) || (ch == 0xAA)) );
+
+ /* Experimental values (Logitech wheelmouse) */
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Last mouse mode: 0x%x\n", ch);
+#endif
+ if ( ch == 3 ) {
+ imps2 = 1;
+ }
+ }
+ }
+ return imps2;
+}
+
+int GS_OpenMouse(_THIS)
+{
+ int i;
+ const char *mousedev;
+ const char *mousedrv;
+
+ mousedrv = SDL_getenv("SDL_MOUSEDRV");
+ mousedev = SDL_getenv("SDL_MOUSEDEV");
+ mouse_fd = -1;
+
+ /* STD MICE */
+
+ if ( mousedev == NULL ) {
+ /* FIXME someday... allow multiple mice in this driver */
+ char *ps2mice[] = {
+ "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL
+ };
+ /* First try to use GPM in repeater mode */
+ if ( mouse_fd < 0 ) {
+ if ( gpm_available() ) {
+ mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using GPM mouse\n");
+#endif
+ mouse_drv = MOUSE_GPM;
+ }
+ }
+ }
+ /* Now try to use a modern PS/2 mouse */
+ for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) {
+ mouse_fd = open(ps2mice[i], O_RDWR, 0);
+ if (mouse_fd < 0) {
+ mouse_fd = open(ps2mice[i], O_RDONLY, 0);
+ }
+ if (mouse_fd >= 0) {
+ /* rcg06112001 Attempt to set IMPS/2 mode */
+ if ( i == 0 ) {
+ set_imps2_mode(mouse_fd);
+ }
+ if (detect_imps2(mouse_fd)) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using IMPS2 mouse\n");
+#endif
+ mouse_drv = MOUSE_IMPS2;
+ } else {
+ mouse_drv = MOUSE_PS2;
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using PS2 mouse\n");
+#endif
+ }
+ }
+ }
+ /* Next try to use a PPC ADB port mouse */
+ if ( mouse_fd < 0 ) {
+ mouse_fd = open("/dev/adbmouse", O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using ADB mouse\n");
+#endif
+ mouse_drv = MOUSE_BM;
+ }
+ }
+ }
+ /* Default to a serial Microsoft mouse */
+ if ( mouse_fd < 0 ) {
+ if ( mousedev == NULL ) {
+ mousedev = "/dev/mouse";
+ }
+ mouse_fd = open(mousedev, O_RDONLY, 0);
+ if ( mouse_fd >= 0 ) {
+ struct termios mouse_termios;
+
+ /* Set the sampling speed to 1200 baud */
+ tcgetattr(mouse_fd, &mouse_termios);
+ mouse_termios.c_iflag = IGNBRK | IGNPAR;
+ mouse_termios.c_oflag = 0;
+ mouse_termios.c_lflag = 0;
+ mouse_termios.c_line = 0;
+ mouse_termios.c_cc[VTIME] = 0;
+ mouse_termios.c_cc[VMIN] = 1;
+ mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL;
+ mouse_termios.c_cflag |= CS8;
+ mouse_termios.c_cflag |= B1200;
+ tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios);
+#ifdef DEBUG_MOUSE
+fprintf(stderr, "Using Microsoft mouse on %s\n", mousedev);
+#endif
+ mouse_drv = MOUSE_MS;
+ }
+ }
+ if ( mouse_fd < 0 ) {
+ mouse_drv = MOUSE_NONE;
+ }
+ return(mouse_fd);
+}
+
+static int posted = 0;
+
+void GS_vgamousecallback(int button, int dx, int dy)
+{
+ int button_1, button_3;
+ int button_state;
+ int state_changed;
+ int i;
+ Uint8 state;
+
+ if ( dx || dy ) {
+ posted += SDL_PrivateMouseMotion(0, 1, dx, dy);
+ }
+
+ /* Swap button 1 and 3 */
+ button_1 = (button & 0x04) >> 2;
+ button_3 = (button & 0x01) << 2;
+ button &= ~0x05;
+ button |= (button_1|button_3);
+
+ /* See what changed */
+ button_state = SDL_GetMouseState(NULL, NULL);
+ state_changed = button_state ^ button;
+ for ( i=0; i<8; ++i ) {
+ if ( state_changed & (1<<i) ) {
+ if ( button & (1<<i) ) {
+ state = SDL_PRESSED;
+ } else {
+ state = SDL_RELEASED;
+ }
+ posted += SDL_PrivateMouseButton(state, i+1, 0, 0);
+ }
+ }
+}
+
+/* For now, use GPM, PS/2, and MS protocols
+ Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.)
+ */
+static void handle_mouse(_THIS)
+{
+ static int start = 0;
+ static unsigned char mousebuf[BUFSIZ];
+ int i, nread;
+ int button = 0;
+ int dx = 0, dy = 0;
+ int packetsize = 0;
+
+ /* Figure out the mouse packet size */
+ switch (mouse_drv) {
+ case MOUSE_NONE:
+ /* Ack! */
+ read(mouse_fd, mousebuf, BUFSIZ);
+ return;
+ case MOUSE_GPM:
+ packetsize = 5;
+ break;
+ case MOUSE_IMPS2:
+ packetsize = 4;
+ break;
+ case MOUSE_PS2:
+ case MOUSE_MS:
+ case MOUSE_BM:
+ packetsize = 3;
+ break;
+ case NUM_MOUSE_DRVS:
+ /* Uh oh.. */
+ packetsize = 0;
+ break;
+ }
+
+ /* Read as many packets as possible */
+ nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start);
+ if ( nread < 0 ) {
+ return;
+ }
+ nread += start;
+#ifdef DEBUG_MOUSE
+ fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start);
+#endif
+ for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) {
+ switch (mouse_drv) {
+ case MOUSE_NONE:
+ break;
+ case MOUSE_GPM:
+ /* GPM protocol has 0x80 in high byte */
+ if ( (mousebuf[i] & 0xF8) != 0x80 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (~mousebuf[i]) & 0x07;
+ dx = (signed char)(mousebuf[i+1]) +
+ (signed char)(mousebuf[i+3]);
+ dy = -((signed char)(mousebuf[i+2]) +
+ (signed char)(mousebuf[i+4]));
+ break;
+ case MOUSE_PS2:
+ /* PS/2 protocol has nothing in high byte */
+ if ( (mousebuf[i] & 0xC0) != 0 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
+ (mousebuf[i] & 0x02) >> 1 | /*Right*/
+ (mousebuf[i] & 0x01) << 2; /*Left*/
+ dx = (mousebuf[i] & 0x10) ?
+ mousebuf[i+1] - 256 : mousebuf[i+1];
+ dy = (mousebuf[i] & 0x20) ?
+ -(mousebuf[i+2] - 256) : -mousebuf[i+2];
+ break;
+ case MOUSE_IMPS2:
+ /* Get current mouse state */
+ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
+ (mousebuf[i] & 0x02) >> 1 | /*Right*/
+ (mousebuf[i] & 0x01) << 2 | /*Left*/
+ (mousebuf[i] & 0x40) >> 3 | /* 4 */
+ (mousebuf[i] & 0x80) >> 3; /* 5 */
+ dx = (mousebuf[i] & 0x10) ?
+ mousebuf[i+1] - 256 : mousebuf[i+1];
+ dy = (mousebuf[i] & 0x20) ?
+ -(mousebuf[i+2] - 256) : -mousebuf[i+2];
+ switch (mousebuf[i+3]&0x0F) {
+ case 0x0E: /* DX = +1 */
+ case 0x02: /* DX = -1 */
+ break;
+ case 0x0F: /* DY = +1 (map button 4) */
+ FB_vgamousecallback(button | (1<<3),
+ 1, 0, 0);
+ break;
+ case 0x01: /* DY = -1 (map button 5) */
+ FB_vgamousecallback(button | (1<<4),
+ 1, 0, 0);
+ break;
+ }
+ break;
+ case MOUSE_MS:
+ /* Microsoft protocol has 0x40 in high byte */
+ if ( (mousebuf[i] & 0x40) != 0x40 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = ((mousebuf[i] & 0x20) >> 3) |
+ ((mousebuf[i] & 0x10) >> 4);
+ dx = (signed char)(((mousebuf[i] & 0x03) << 6) |
+ (mousebuf[i + 1] & 0x3F));
+ dy = (signed char)(((mousebuf[i] & 0x0C) << 4) |
+ (mousebuf[i + 2] & 0x3F));
+ break;
+ case MOUSE_BM:
+ /* BusMouse protocol has 0xF8 in high byte */
+ if ( (mousebuf[i] & 0xF8) != 0x80 ) {
+ /* Go to next byte */
+ i -= (packetsize-1);
+ continue;
+ }
+ /* Get current mouse state */
+ button = (~mousebuf[i]) & 0x07;
+ dx = (signed char)mousebuf[i+1];
+ dy = -(signed char)mousebuf[i+2];
+ break;
+ case NUM_MOUSE_DRVS:
+ /* Uh oh.. */
+ dx = 0;
+ dy = 0;
+ break;
+ }
+ GS_vgamousecallback(button, dx, dy);
+ }
+ if ( i < nread ) {
+ SDL_memcpy(mousebuf, &mousebuf[i], (nread-i));
+ start = (nread-i);
+ } else {
+ start = 0;
+ }
+ return;
+}
+
+static void handle_keyboard(_THIS)
+{
+ unsigned char keybuf[BUFSIZ];
+ int i, nread;
+ int pressed;
+ int scancode;
+ SDL_keysym keysym;
+
+ nread = read(keyboard_fd, keybuf, BUFSIZ);
+ for ( i=0; i<nread; ++i ) {
+ scancode = keybuf[i] & 0x7F;
+ if ( keybuf[i] & 0x80 ) {
+ pressed = SDL_RELEASED;
+ } else {
+ pressed = SDL_PRESSED;
+ }
+ TranslateKey(scancode, &keysym);
+ posted += SDL_PrivateKeyboard(pressed, &keysym);
+ }
+}
+
+void GS_PumpEvents(_THIS)
+{
+ fd_set fdset;
+ int max_fd;
+ static struct timeval zero;
+
+ do {
+ posted = 0;
+
+ FD_ZERO(&fdset);
+ max_fd = 0;
+ if ( keyboard_fd >= 0 ) {
+ FD_SET(keyboard_fd, &fdset);
+ if ( max_fd < keyboard_fd ) {
+ max_fd = keyboard_fd;
+ }
+ }
+ if ( mouse_fd >= 0 ) {
+ FD_SET(mouse_fd, &fdset);
+ if ( max_fd < mouse_fd ) {
+ max_fd = mouse_fd;
+ }
+ }
+ if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) {
+ if ( keyboard_fd >= 0 ) {
+ if ( FD_ISSET(keyboard_fd, &fdset) ) {
+ handle_keyboard(this);
+ }
+ }
+ if ( mouse_fd >= 0 ) {
+ if ( FD_ISSET(mouse_fd, &fdset) ) {
+ handle_mouse(this);
+ }
+ }
+ }
+ } while ( posted );
+}
+
+void GS_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the Linux key translation table */
+
+ /* First get the ascii keys and others not well handled */
+ for (i=0; i<SDL_arraysize(keymap); ++i) {
+ switch(i) {
+ /* These aren't handled by the x86 kernel keymapping (?) */
+ case SCANCODE_PRINTSCREEN:
+ keymap[i] = SDLK_PRINT;
+ break;
+ case SCANCODE_BREAK:
+ keymap[i] = SDLK_BREAK;
+ break;
+ case SCANCODE_BREAK_ALTERNATIVE:
+ keymap[i] = SDLK_PAUSE;
+ break;
+ case SCANCODE_LEFTSHIFT:
+ keymap[i] = SDLK_LSHIFT;
+ break;
+ case SCANCODE_RIGHTSHIFT:
+ keymap[i] = SDLK_RSHIFT;
+ break;
+ case SCANCODE_LEFTCONTROL:
+ keymap[i] = SDLK_LCTRL;
+ break;
+ case SCANCODE_RIGHTCONTROL:
+ keymap[i] = SDLK_RCTRL;
+ break;
+ case SCANCODE_RIGHTWIN:
+ keymap[i] = SDLK_RSUPER;
+ break;
+ case SCANCODE_LEFTWIN:
+ keymap[i] = SDLK_LSUPER;
+ break;
+ case 127:
+ keymap[i] = SDLK_MENU;
+ break;
+ /* this should take care of all standard ascii keys */
+ default:
+ keymap[i] = KVAL(vga_keymap[0][i]);
+ break;
+ }
+ }
+ for (i=0; i<SDL_arraysize(keymap); ++i) {
+ switch(keymap_temp[i]) {
+ case K_F1: keymap[i] = SDLK_F1; break;
+ case K_F2: keymap[i] = SDLK_F2; break;
+ case K_F3: keymap[i] = SDLK_F3; break;
+ case K_F4: keymap[i] = SDLK_F4; break;
+ case K_F5: keymap[i] = SDLK_F5; break;
+ case K_F6: keymap[i] = SDLK_F6; break;
+ case K_F7: keymap[i] = SDLK_F7; break;
+ case K_F8: keymap[i] = SDLK_F8; break;
+ case K_F9: keymap[i] = SDLK_F9; break;
+ case K_F10: keymap[i] = SDLK_F10; break;
+ case K_F11: keymap[i] = SDLK_F11; break;
+ case K_F12: keymap[i] = SDLK_F12; break;
+
+ case K_DOWN: keymap[i] = SDLK_DOWN; break;
+ case K_LEFT: keymap[i] = SDLK_LEFT; break;
+ case K_RIGHT: keymap[i] = SDLK_RIGHT; break;
+ case K_UP: keymap[i] = SDLK_UP; break;
+
+ case K_P0: keymap[i] = SDLK_KP0; break;
+ case K_P1: keymap[i] = SDLK_KP1; break;
+ case K_P2: keymap[i] = SDLK_KP2; break;
+ case K_P3: keymap[i] = SDLK_KP3; break;
+ case K_P4: keymap[i] = SDLK_KP4; break;
+ case K_P5: keymap[i] = SDLK_KP5; break;
+ case K_P6: keymap[i] = SDLK_KP6; break;
+ case K_P7: keymap[i] = SDLK_KP7; break;
+ case K_P8: keymap[i] = SDLK_KP8; break;
+ case K_P9: keymap[i] = SDLK_KP9; break;
+ case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break;
+ case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break;
+ case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break;
+ case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break;
+ case K_PENTER: keymap[i] = SDLK_KP_ENTER; break;
+ case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break;
+
+ case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT )
+ keymap[i] = SDLK_LSHIFT;
+ break;
+ case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break;
+ case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break;
+ case K_CTRL: if ( keymap[i] != SDLK_RCTRL )
+ keymap[i] = SDLK_LCTRL;
+ break;
+ case K_CTRLL: keymap[i] = SDLK_LCTRL; break;
+ case K_CTRLR: keymap[i] = SDLK_RCTRL; break;
+ case K_ALT: keymap[i] = SDLK_LALT; break;
+ case K_ALTGR: keymap[i] = SDLK_RALT; break;
+
+ case K_INSERT: keymap[i] = SDLK_INSERT; break;
+ case K_REMOVE: keymap[i] = SDLK_DELETE; break;
+ case K_PGUP: keymap[i] = SDLK_PAGEUP; break;
+ case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break;
+ case K_FIND: keymap[i] = SDLK_HOME; break;
+ case K_SELECT: keymap[i] = SDLK_END; break;
+
+ case K_NUM: keymap[i] = SDLK_NUMLOCK; break;
+ case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break;
+
+ case K_F13: keymap[i] = SDLK_PRINT; break;
+ case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break;
+ case K_PAUSE: keymap[i] = SDLK_PAUSE; break;
+
+ case 127: keymap[i] = SDLK_BACKSPACE; break;
+
+ default: break;
+ }
+ }
+}
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE ) {
+ int map;
+ SDLMod modstate;
+
+ modstate = SDL_GetModState();
+ map = 0;
+ if ( modstate & KMOD_SHIFT ) {
+ map |= (1<<KG_SHIFT);
+ }
+ if ( modstate & KMOD_CTRL ) {
+ map |= (1<<KG_CTRL);
+ }
+ if ( modstate & KMOD_ALT ) {
+ map |= (1<<KG_ALT);
+ }
+ if ( modstate & KMOD_MODE ) {
+ map |= (1<<KG_ALTGR);
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) {
+ if ( modstate & KMOD_CAPS ) {
+ map ^= (1<<KG_SHIFT);
+ }
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) {
+ if ( modstate & KMOD_NUM ) {
+ keysym->unicode=KVAL(vga_keymap[map][scancode]);
+ }
+ } else {
+ keysym->unicode = KVAL(vga_keymap[map][scancode]);
+ }
+ }
+ return(keysym);
+}
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents_c.h b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents_c.h
new file mode 100644
index 0000000..6758ab3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsevents_c.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_gsvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern int GS_OpenKeyboard(_THIS);
+extern void GS_CloseKeyboard(_THIS);
+extern int GS_OpenMouse(_THIS);
+extern void GS_CloseMouse(_THIS);
+extern int GS_EnterGraphicsMode(_THIS);
+extern int GS_InGraphicsMode(_THIS);
+extern void GS_LeaveGraphicsMode(_THIS);
+
+extern void GS_InitOSKeymap(_THIS);
+extern void GS_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gskeys.h b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gskeys.h
new file mode 100644
index 0000000..2b01b6b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gskeys.h
@@ -0,0 +1,139 @@
+
+/* Scancodes for the Linux framebuffer console
+ - Taken with thanks from SVGAlib 1.4.0
+*/
+
+#define SCANCODE_ESCAPE 1
+
+#define SCANCODE_1 2
+#define SCANCODE_2 3
+#define SCANCODE_3 4
+#define SCANCODE_4 5
+#define SCANCODE_5 6
+#define SCANCODE_6 7
+#define SCANCODE_7 8
+#define SCANCODE_8 9
+#define SCANCODE_9 10
+#define SCANCODE_0 11
+
+#define SCANCODE_MINUS 12
+#define SCANCODE_EQUAL 13
+
+#define SCANCODE_BACKSPACE 14
+#define SCANCODE_TAB 15
+
+#define SCANCODE_Q 16
+#define SCANCODE_W 17
+#define SCANCODE_E 18
+#define SCANCODE_R 19
+#define SCANCODE_T 20
+#define SCANCODE_Y 21
+#define SCANCODE_U 22
+#define SCANCODE_I 23
+#define SCANCODE_O 24
+#define SCANCODE_P 25
+#define SCANCODE_BRACKET_LEFT 26
+#define SCANCODE_BRACKET_RIGHT 27
+
+#define SCANCODE_ENTER 28
+
+#define SCANCODE_LEFTCONTROL 29
+
+#define SCANCODE_A 30
+#define SCANCODE_S 31
+#define SCANCODE_D 32
+#define SCANCODE_F 33
+#define SCANCODE_G 34
+#define SCANCODE_H 35
+#define SCANCODE_J 36
+#define SCANCODE_K 37
+#define SCANCODE_L 38
+#define SCANCODE_SEMICOLON 39
+#define SCANCODE_APOSTROPHE 40
+#define SCANCODE_GRAVE 41
+
+#define SCANCODE_LEFTSHIFT 42
+#define SCANCODE_BACKSLASH 43
+
+#define SCANCODE_Z 44
+#define SCANCODE_X 45
+#define SCANCODE_C 46
+#define SCANCODE_V 47
+#define SCANCODE_B 48
+#define SCANCODE_N 49
+#define SCANCODE_M 50
+#define SCANCODE_COMMA 51
+#define SCANCODE_PERIOD 52
+#define SCANCODE_SLASH 53
+
+#define SCANCODE_RIGHTSHIFT 54
+#define SCANCODE_KEYPADMULTIPLY 55
+
+#define SCANCODE_LEFTALT 56
+#define SCANCODE_SPACE 57
+#define SCANCODE_CAPSLOCK 58
+
+#define SCANCODE_F1 59
+#define SCANCODE_F2 60
+#define SCANCODE_F3 61
+#define SCANCODE_F4 62
+#define SCANCODE_F5 63
+#define SCANCODE_F6 64
+#define SCANCODE_F7 65
+#define SCANCODE_F8 66
+#define SCANCODE_F9 67
+#define SCANCODE_F10 68
+
+#define SCANCODE_NUMLOCK 69
+#define SCANCODE_SCROLLLOCK 70
+
+#define SCANCODE_KEYPAD7 71
+#define SCANCODE_CURSORUPLEFT 71
+#define SCANCODE_KEYPAD8 72
+#define SCANCODE_CURSORUP 72
+#define SCANCODE_KEYPAD9 73
+#define SCANCODE_CURSORUPRIGHT 73
+#define SCANCODE_KEYPADMINUS 74
+#define SCANCODE_KEYPAD4 75
+#define SCANCODE_CURSORLEFT 75
+#define SCANCODE_KEYPAD5 76
+#define SCANCODE_KEYPAD6 77
+#define SCANCODE_CURSORRIGHT 77
+#define SCANCODE_KEYPADPLUS 78
+#define SCANCODE_KEYPAD1 79
+#define SCANCODE_CURSORDOWNLEFT 79
+#define SCANCODE_KEYPAD2 80
+#define SCANCODE_CURSORDOWN 80
+#define SCANCODE_KEYPAD3 81
+#define SCANCODE_CURSORDOWNRIGHT 81
+#define SCANCODE_KEYPAD0 82
+#define SCANCODE_KEYPADPERIOD 83
+
+#define SCANCODE_LESS 86
+
+#define SCANCODE_F11 87
+#define SCANCODE_F12 88
+
+#define SCANCODE_KEYPADENTER 96
+#define SCANCODE_RIGHTCONTROL 97
+#define SCANCODE_CONTROL 97
+#define SCANCODE_KEYPADDIVIDE 98
+#define SCANCODE_PRINTSCREEN 99
+#define SCANCODE_RIGHTALT 100
+#define SCANCODE_BREAK 101 /* Beware: is 119 */
+#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
+
+#define SCANCODE_HOME 102
+#define SCANCODE_CURSORBLOCKUP 103 /* Cursor key block */
+#define SCANCODE_PAGEUP 104
+#define SCANCODE_CURSORBLOCKLEFT 105 /* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT 106 /* Cursor key block */
+#define SCANCODE_END 107
+#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
+#define SCANCODE_PAGEDOWN 109
+#define SCANCODE_INSERT 110
+#define SCANCODE_REMOVE 111
+
+#define SCANCODE_RIGHTWIN 126
+#define SCANCODE_LEFTWIN 125
+
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse.c b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse.c
new file mode 100644
index 0000000..e0d320d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse.c
@@ -0,0 +1,146 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <sys/ioctl.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_gsvideo.h"
+#include "SDL_gsmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
+
+/* There isn't any implementation dependent data */
+void GS_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ return;
+}
+
+/* There isn't any implementation dependent data */
+WMcursor *GS_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ return((WMcursor *)0x01);
+}
+
+static void GS_MoveCursor(_THIS, SDL_Cursor *cursor, int x, int y)
+{
+ SDL_Surface *screen;
+ struct ps2_image image;
+ SDL_Rect area;
+ int mouse_y1, mouse_y2;
+ void *saved_pixels;
+ int screen_updated;
+
+ /* Lock so we don't interrupt an update with mouse motion */
+ SDL_LockCursor();
+
+ /* Make sure any pending DMA has completed */
+ if ( dma_pending ) {
+ ioctl(console_fd, PS2IOC_SENDQCT, 1);
+ dma_pending = 0;
+ }
+
+ /* Remove the cursor image from the DMA area */
+ screen = this->screen;
+ saved_pixels = screen->pixels;
+ screen->pixels = mapped_mem + screen->offset;
+ screen_updated = 0;
+ if ( cursor_drawn ) {
+ SDL_EraseCursorNoLock(screen);
+ cursor_drawn = 0;
+ screen_updated = 1;
+ }
+
+ /* Save the current mouse area */
+ SDL_MouseRect(&area);
+ mouse_y1 = area.y;
+ mouse_y2 = area.y+area.h;
+
+ /* Only draw the new cursor if there was one passed in */
+ if ( cursor ) {
+ /* Set the new location */
+ cursor->area.x = (x - cursor->hot_x);
+ cursor->area.y = (y - cursor->hot_y);
+
+ /* Draw the cursor at the new location */
+ if ( (SDL_cursorstate & CURSOR_VISIBLE) && screen->pixels ) {
+ SDL_DrawCursorNoLock(screen);
+ cursor_drawn = 1;
+ screen_updated = 1;
+ }
+ }
+ screen->pixels = saved_pixels;
+
+ /* Update the affected area of the screen */
+ if ( screen_updated ) {
+ SDL_MouseRect(&area);
+ if ( area.y < mouse_y1 ) {
+ mouse_y1 = area.y;
+ }
+ if ( (area.y+area.h) > mouse_y2 ) {
+ mouse_y2 = area.y+area.h;
+ }
+ image = screen_image;
+ image.y += screen->offset / screen->pitch + mouse_y1;
+ image.h = mouse_y2 - mouse_y1;
+ image.ptr = mapped_mem +
+ (image.y - screen_image.y) * screen->pitch;
+ ioctl(console_fd, PS2IOC_LOADIMAGE, &image);
+
+ /* Need to scale offscreen image to TV output */
+ if ( image.y > 0 ) {
+ scaleimage_nonblock(console_fd,
+ tex_tags_mem, scale_tags_mem);
+ }
+ }
+
+ /* We're finished */
+ SDL_UnlockCursor();
+}
+
+void GS_MoveWMCursor(_THIS, int x, int y)
+{
+ GS_MoveCursor(this, SDL_cursor, x, y);
+}
+
+int GS_ShowWMCursor(_THIS, WMcursor *wmcursor)
+{
+ SDL_Cursor *cursor;
+ int x, y;
+
+ /* Draw the cursor at the appropriate location */
+ SDL_GetMouseState(&x, &y);
+ if ( wmcursor ) {
+ cursor = SDL_cursor;
+ } else {
+ cursor = NULL;
+ }
+ GS_MoveCursor(this, cursor, x, y);
+ return(1);
+}
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse_c.h b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse_c.h
new file mode 100644
index 0000000..c507ed4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsmouse_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_gsvideo.h"
+
+/* This is the maximum size of the cursor sprite */
+#define CURSOR_W 32
+#define CURSOR_H 32
+#define CURSOR_W_POW 5 /* 32 = 2^5 */
+#define CURSOR_H_POW 5 /* 32 = 2^5 */
+
+/* Functions to be exported */
+extern void GS_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *GS_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern void GS_MoveWMCursor(_THIS, int x, int y);
+extern int GS_ShowWMCursor(_THIS, WMcursor *cursor);
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.c b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.c
new file mode 100644
index 0000000..e172c60
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.c
@@ -0,0 +1,689 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Framebuffer console based SDL video driver implementation.
+*/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#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_cursor_c.h"
+#include "SDL_gsvideo.h"
+#include "SDL_gsmouse_c.h"
+#include "SDL_gsevents_c.h"
+#include "SDL_gsyuv_c.h"
+
+
+/* Initialization/Query functions */
+static int GS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void GS_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int GS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int GS_LockHWSurface(_THIS, SDL_Surface *surface);
+static void GS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void GS_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* GS driver bootstrap functions */
+
+static int GS_Available(void)
+{
+ int console, memory;
+
+ console = open(PS2_DEV_GS, O_RDWR, 0);
+ if ( console >= 0 ) {
+ close(console);
+ }
+ memory = open(PS2_DEV_MEM, O_RDWR, 0);
+ if ( memory >= 0 ) {
+ close(memory);
+ }
+ return((console >= 0) && (memory >= 0));
+}
+
+static void GS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *GS_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *this;
+
+ /* Initialize all variables that we clean on shutdown */
+ this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( this ) {
+ SDL_memset(this, 0, (sizeof *this));
+ this->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *this->hidden));
+ }
+ if ( (this == NULL) || (this->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( this ) {
+ SDL_free(this);
+ }
+ return(0);
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+ mouse_fd = -1;
+ keyboard_fd = -1;
+
+ /* Set the function pointers */
+ this->VideoInit = GS_VideoInit;
+ this->ListModes = GS_ListModes;
+ this->SetVideoMode = GS_SetVideoMode;
+ this->CreateYUVOverlay = GS_CreateYUVOverlay;
+ this->SetColors = GS_SetColors;
+ this->UpdateRects = NULL;
+ this->VideoQuit = GS_VideoQuit;
+ this->AllocHWSurface = GS_AllocHWSurface;
+ this->CheckHWBlit = NULL;
+ this->FillHWRect = NULL;
+ this->SetHWColorKey = NULL;
+ this->SetHWAlpha = NULL;
+ this->LockHWSurface = GS_LockHWSurface;
+ this->UnlockHWSurface = GS_UnlockHWSurface;
+ this->FlipHWSurface = NULL;
+ this->FreeHWSurface = GS_FreeHWSurface;
+ this->SetIcon = NULL;
+ this->SetCaption = NULL;
+ this->GetWMInfo = NULL;
+ this->FreeWMCursor = GS_FreeWMCursor;
+ this->CreateWMCursor = GS_CreateWMCursor;
+ this->ShowWMCursor = GS_ShowWMCursor;
+ this->MoveWMCursor = GS_MoveWMCursor;
+ this->InitOSKeymap = GS_InitOSKeymap;
+ this->PumpEvents = GS_PumpEvents;
+
+ this->free = GS_DeleteDevice;
+
+ return this;
+}
+
+VideoBootStrap PS2GS_bootstrap = {
+ "ps2gs", "PlayStation 2 Graphics Synthesizer",
+ GS_Available, GS_CreateDevice
+};
+
+/* These are the pixel formats for the 32, 24, and 16 bit video modes */
+static struct {
+ int bpp;
+ Uint32 r;
+ Uint32 g;
+ Uint32 b;
+} GS_pixelmasks[] = {
+ { 32, 0x000000FF, /* RGB little-endian */
+ 0x0000FF00,
+ 0x00FF0000 },
+ { 24, 0x000000FF, /* RGB little-endian */
+ 0x0000FF00,
+ 0x00FF0000 },
+ { 16, 0x0000001f, /* RGB little-endian */
+ 0x000003e0,
+ 0x00007c00 },
+};
+/* This is a mapping from SDL bytes-per-pixel to GS pixel format */
+static int GS_formatmap[] = {
+ -1, /* 0 bpp, not a legal value */
+ -1, /* 8 bpp, not supported (yet?) */
+ PS2_GS_PSMCT16, /* 16 bpp */
+ PS2_GS_PSMCT24, /* 24 bpp */
+ PS2_GS_PSMCT32 /* 32 bpp */
+};
+
+static unsigned long long head_tags[] __attribute__((aligned(16))) = {
+ 4 | (1LL << 60), /* GIFtag */
+ 0x0e, /* A+D */
+ 0, /* 2 */
+ PS2_GS_BITBLTBUF,
+ 0, /* 4 */
+ PS2_GS_TRXPOS,
+ 0, /* 6 */
+ PS2_GS_TRXREG,
+ 0, /* 8 */
+ PS2_GS_TRXDIR
+};
+
+#define MAXIMG (32767 * 16)
+#define MAXTAGS 8
+
+static inline int loadimage_nonblock(int fd, struct ps2_image *image, int size,
+ unsigned long long *hm,
+ unsigned long long *im)
+{
+ struct ps2_plist plist;
+ struct ps2_packet packet[1 + MAXTAGS * 2];
+ int isize;
+ int pnum, it, eop;
+ char *data;
+
+ /* initialize the variables */
+ data = (char *)image->ptr;
+ pnum = it = eop = 0;
+ plist.packet = packet;
+
+ /* make BITBLT packet */
+ packet[pnum].ptr = hm;
+ packet[pnum].len = sizeof(head_tags);
+ pnum++;
+ hm[2] = ((unsigned long long)image->fbp << 32) |
+ ((unsigned long long)image->fbw << 48) |
+ ((unsigned long long)image->psm << 56);
+ hm[4] = ((unsigned long long)image->x << 32) |
+ ((unsigned long long)image->y << 48);
+ hm[6] = (unsigned long long)image->w |
+ ((unsigned long long)image->h << 32);
+
+ /* make image mode tags */
+ while (!eop) {
+ isize = size > MAXIMG ? MAXIMG : size;
+ size -= isize;
+ eop = (size == 0);
+
+ packet[pnum].ptr = &im[it];
+ packet[pnum].len = sizeof(unsigned long long) * 2;
+ pnum++;
+ im[it++] = (isize >> 4) | (eop ? (1 << 15) : 0) | (2LL << 58);
+ im[it++] = 0;
+
+ packet[pnum].ptr = (void *)data;
+ packet[pnum].len = isize;
+ pnum++;
+ data += isize;
+ }
+ plist.num = pnum;
+
+ return ioctl(fd, PS2IOC_SENDL, &plist);
+}
+
+static unsigned long long tex_tags[] __attribute__((aligned(16))) = {
+ 3 | (1LL << 60), /* GIFtag */
+ 0x0e, /* A+D */
+ 0, /* 2 */
+ PS2_GS_TEX0_1,
+ (1 << 5) + (1 << 6),
+ PS2_GS_TEX1_1,
+ 0,
+ PS2_GS_TEXFLUSH
+};
+static unsigned long long scale_tags[] __attribute__((aligned(16))) = {
+ 5 | (1LL << 60), /* GIFtag */
+ 0x0e, /* A+D */
+ 6 + (1 << 4) + (1 << 8),
+ PS2_GS_PRIM,
+ ((unsigned long long)0 * 16) + (((unsigned long long)0 * 16) << 16),
+ PS2_GS_UV,
+ ((unsigned long long)0 * 16) + (((unsigned long long)0 * 16) << 16),
+ PS2_GS_XYZ2,
+ 0, /* 8 */
+ PS2_GS_UV,
+ 0, /* 10 */
+ PS2_GS_XYZ2
+};
+
+
+int scaleimage_nonblock(int fd, unsigned long long *tm, unsigned long long *sm)
+{
+ struct ps2_plist plist;
+ struct ps2_packet packet[2];
+
+ /* initialize the variables */
+ plist.num = 2;
+ plist.packet = packet;
+
+ packet[0].ptr = tm;
+ packet[0].len = sizeof(tex_tags);
+ packet[1].ptr = sm;
+ packet[1].len = sizeof(scale_tags);
+
+ return ioctl(fd, PS2IOC_SENDL, &plist);
+}
+
+static int power_of_2(int value)
+{
+ int shift;
+
+ for ( shift = 0; (1<<shift) < value; ++shift ) {
+ /* Keep looking */ ;
+ }
+ return(shift);
+}
+
+static int GS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ struct ps2_screeninfo vinfo;
+
+ /* Initialize the library */
+ console_fd = open(PS2_DEV_GS, O_RDWR, 0);
+ if ( console_fd < 0 ) {
+ SDL_SetError("Unable to open %s", PS2_DEV_GS);
+ return(-1);
+ }
+ memory_fd = open(PS2_DEV_MEM, O_RDWR, 0);
+ if ( memory_fd < 0 ) {
+ close(console_fd);
+ console_fd = -1;
+ SDL_SetError("Unable to open %s", PS2_DEV_MEM);
+ return(-1);
+ }
+
+ if ( ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0 ) {
+ close(memory_fd);
+ close(console_fd);
+ console_fd = -1;
+ SDL_SetError("Couldn't get console pixel format");
+ return(-1);
+ }
+
+ /* Determine the current screen size */
+ this->info.current_w = vinfo.w;
+ this->info.current_h = vinfo.h;
+
+ /* Determine the current screen depth */
+ switch (vinfo.psm) {
+ /* Supported pixel formats */
+ case PS2_GS_PSMCT32:
+ case PS2_GS_PSMCT24:
+ case PS2_GS_PSMCT16:
+ break;
+ default:
+ GS_VideoQuit(this);
+ SDL_SetError("Unknown console pixel format: %d", vinfo.psm);
+ return(-1);
+ }
+ vformat->BitsPerPixel = GS_pixelmasks[vinfo.psm].bpp;
+ vformat->Rmask = GS_pixelmasks[vinfo.psm].r;
+ vformat->Gmask = GS_pixelmasks[vinfo.psm].g;
+ vformat->Bmask = GS_pixelmasks[vinfo.psm].b;
+ saved_vinfo = vinfo;
+
+ /* Enable mouse and keyboard support */
+ if ( GS_OpenKeyboard(this) < 0 ) {
+ GS_VideoQuit(this);
+ SDL_SetError("Unable to open keyboard");
+ return(-1);
+ }
+ if ( GS_OpenMouse(this) < 0 ) {
+ const char *sdl_nomouse;
+
+ sdl_nomouse = SDL_getenv("SDL_NOMOUSE");
+ if ( ! sdl_nomouse ) {
+ GS_VideoQuit(this);
+ SDL_SetError("Unable to open mouse");
+ return(-1);
+ }
+ }
+
+ /* We're done! */
+ return(0);
+}
+
+static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ static SDL_Rect GS_vesa_mode_list[] = {
+ { 0, 0, 1280, 1024 },
+ { 0, 0, 1024, 768 },
+ { 0, 0, 800, 600 },
+ { 0, 0, 640, 480 }
+ };
+ static SDL_Rect *GS_vesa_modes[] = {
+ &GS_vesa_mode_list[0],
+ &GS_vesa_mode_list[1],
+ &GS_vesa_mode_list[2],
+ &GS_vesa_mode_list[3],
+ NULL
+ };
+ static SDL_Rect GS_tvout_stretch;
+ static SDL_Rect GS_tvout_mode;
+ static SDL_Rect *GS_tvout_modes[3];
+ SDL_Rect **modes = NULL;
+
+ switch (format->BitsPerPixel) {
+ case 16:
+ case 24:
+ case 32:
+ if ( saved_vinfo.mode == PS2_GS_VESA ) {
+ modes = GS_vesa_modes;
+ } else {
+ int i, j = 0;
+
+// FIXME - what's wrong with the stretch code at 16 bpp?
+if ( format->BitsPerPixel != 32 ) break;
+ /* Add a mode that we could possibly stretch to */
+ for ( i=0; GS_vesa_modes[i]; ++i ) {
+ if ( (GS_vesa_modes[i]->w == saved_vinfo.w) &&
+ (GS_vesa_modes[i]->h != saved_vinfo.h) ) {
+ GS_tvout_stretch.w=GS_vesa_modes[i]->w;
+ GS_tvout_stretch.h=GS_vesa_modes[i]->h;
+ GS_tvout_modes[j++] = &GS_tvout_stretch;
+ break;
+ }
+ }
+ /* Add the current TV video mode */
+ GS_tvout_mode.w = saved_vinfo.w;
+ GS_tvout_mode.h = saved_vinfo.h;
+ GS_tvout_modes[j++] = &GS_tvout_mode;
+ GS_tvout_modes[j++] = NULL;
+
+ /* Return the created list of modes */
+ modes = GS_tvout_modes;
+ }
+ break;
+ default:
+ break;
+ }
+ return(modes);
+}
+
+/* Various screen update functions available */
+static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ struct ps2_screeninfo vinfo;
+
+ /* Set the terminal into graphics mode */
+ if ( GS_EnterGraphicsMode(this) < 0 ) {
+ return(NULL);
+ }
+
+ /* Set the video mode and get the final screen format */
+ if ( ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't get console screen info");
+ return(NULL);
+ }
+ if ( (vinfo.w != width) || (vinfo.h != height) ||
+ (GS_pixelmasks[vinfo.psm].bpp != bpp) ) {
+ /* If we're not in VESA mode, we have to scale resolution */
+ if ( saved_vinfo.mode == PS2_GS_VESA ) {
+ switch (width) {
+ case 640:
+ vinfo.res = PS2_GS_640x480;
+ break;
+ case 800:
+ vinfo.res = PS2_GS_800x600;
+ break;
+ case 1024:
+ vinfo.res = PS2_GS_1024x768;
+ break;
+ case 1280:
+ vinfo.res = PS2_GS_1280x1024;
+ break;
+ default:
+ SDL_SetError("Unsupported resolution: %dx%d\n",
+ width, height);
+ return(NULL);
+ }
+ vinfo.res |= (PS2_GS_75Hz << 8);
+ vinfo.w = width;
+ vinfo.h = height;
+ }
+ vinfo.fbp = 0;
+ vinfo.psm = GS_formatmap[bpp/8];
+ if ( vinfo.psm < 0 ) {
+ SDL_SetError("Unsupported depth: %d bpp\n", bpp);
+ return(NULL);
+ }
+ if ( ioctl(console_fd, PS2IOC_SSCREENINFO, &vinfo) < 0 ) {
+ SDL_SetError("Couldn't set console screen info");
+ return(NULL);
+ }
+
+ /* Unmap the previous DMA buffer */
+ if ( mapped_mem ) {
+ munmap(mapped_mem, mapped_len);
+ mapped_mem = NULL;
+ }
+ }
+ if ( ! SDL_ReallocFormat(current, GS_pixelmasks[vinfo.psm].bpp,
+ GS_pixelmasks[vinfo.psm].r,
+ GS_pixelmasks[vinfo.psm].g,
+ GS_pixelmasks[vinfo.psm].b, 0) ) {
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = SDL_FULLSCREEN;
+ current->w = width;
+ current->h = height;
+ current->pitch = SDL_CalculatePitch(current);
+
+ /* Memory map the DMA area for block memory transfer */
+ if ( ! mapped_mem ) {
+ pixels_len = height * current->pitch;
+ mapped_len = pixels_len +
+ /* Screen update DMA command area */
+ sizeof(head_tags) + ((2 * MAXTAGS) * 16);
+ if ( saved_vinfo.mode != PS2_GS_VESA ) {
+ mapped_len += sizeof(tex_tags) + sizeof(scale_tags);
+ }
+ mapped_mem = mmap(0, mapped_len, PROT_READ|PROT_WRITE,
+ MAP_SHARED, memory_fd, 0);
+ if ( mapped_mem == MAP_FAILED ) {
+ SDL_SetError("Unable to map %d bytes for DMA",
+ mapped_len);
+ mapped_mem = NULL;
+ return(NULL);
+ }
+
+ /* Set up the entire screen for DMA transfer */
+ screen_image.ptr = mapped_mem;
+ screen_image.fbp = 0;
+ screen_image.fbw = (vinfo.w + 63) / 64;
+ screen_image.psm = vinfo.psm;
+ screen_image.x = 0;
+ if ( vinfo.h == height ) {
+ screen_image.y = 0;
+ } else {
+ /* Put image offscreen and scale to screen height */
+ screen_image.y = vinfo.h;
+ }
+ screen_image.w = current->w;
+ screen_image.h = current->h;
+
+ /* get screen image data size (qword aligned) */
+ screen_image_size = (screen_image.w * screen_image.h);
+ switch (screen_image.psm) {
+ case PS2_GS_PSMCT32:
+ screen_image_size *= 4;
+ break;
+ case PS2_GS_PSMCT24:
+ screen_image_size *= 3;
+ break;
+ case PS2_GS_PSMCT16:
+ screen_image_size *= 2;
+ break;
+ }
+ screen_image_size = (screen_image_size + 15) & ~15;
+
+ /* Set up the memory for screen update DMA commands */
+ head_tags_mem = (unsigned long long *)
+ (mapped_mem + pixels_len);
+ image_tags_mem = (unsigned long long *)
+ ((caddr_t)head_tags_mem + sizeof(head_tags));
+ SDL_memcpy(head_tags_mem, head_tags, sizeof(head_tags));
+ if ( saved_vinfo.mode != PS2_GS_VESA ) {
+ tex_tags_mem = (unsigned long long *)
+ ((caddr_t)image_tags_mem + ((2*MAXTAGS)*16));
+ scale_tags_mem = (unsigned long long *)
+ ((caddr_t)tex_tags_mem + sizeof(tex_tags));
+ SDL_memcpy(tex_tags_mem, tex_tags, sizeof(tex_tags));
+ tex_tags_mem[2] =
+ (vinfo.h * vinfo.w) / 64 +
+ ((unsigned long long)screen_image.fbw << 14) +
+ ((unsigned long long)screen_image.psm << 20) +
+ ((unsigned long long)power_of_2(screen_image.w) << 26) +
+ ((unsigned long long)power_of_2(screen_image.h) << 30) +
+ ((unsigned long long)1 << 34) +
+ ((unsigned long long)1 << 35);
+ SDL_memcpy(scale_tags_mem, scale_tags, sizeof(scale_tags));
+ scale_tags_mem[8] =
+ ((unsigned long long)screen_image.w * 16) +
+ (((unsigned long long)screen_image.h * 16) << 16);
+ scale_tags_mem[10] =
+ ((unsigned long long)vinfo.w * 16) +
+ (((unsigned long long)vinfo.h * 16) << 16);
+ }
+ }
+ current->pixels = NULL;
+ if ( SDL_getenv("SDL_FULLSCREEN_UPDATE") ) {
+ /* Correct semantics */
+ current->flags |= SDL_ASYNCBLIT;
+ } else {
+ /* We lie here - the screen memory isn't really the visible
+ display memory and still requires an update, but this
+ has the desired effect for most applications.
+ */
+ current->flags |= SDL_HWSURFACE;
+ }
+
+ /* Set the update rectangle function */
+ this->UpdateRects = GS_DMAFullUpdate;
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't support hardware surfaces yet */
+static int GS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void GS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+static int GS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface == this->screen ) {
+ /* Since mouse motion affects 'pixels', lock it */
+ SDL_LockCursor();
+
+ /* Make sure any pending DMA has completed */
+ if ( dma_pending ) {
+ ioctl(console_fd, PS2IOC_SENDQCT, 1);
+ dma_pending = 0;
+ }
+
+ /* If the cursor is drawn on the DMA area, remove it */
+ if ( cursor_drawn ) {
+ surface->pixels = mapped_mem + surface->offset;
+ SDL_EraseCursorNoLock(this->screen);
+ cursor_drawn = 0;
+ }
+
+ /* Set the surface pixels to the base of the DMA area */
+ surface->pixels = mapped_mem;
+
+ /* We're finished! */
+ SDL_UnlockCursor();
+ }
+ return(0);
+}
+static void GS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface == this->screen ) {
+ /* Since mouse motion affects 'pixels', lock it */
+ SDL_LockCursor();
+ surface->pixels = NULL;
+ SDL_UnlockCursor();
+ }
+}
+
+static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ /* Lock so we aren't interrupted by a mouse update */
+ SDL_LockCursor();
+
+ /* Make sure any pending DMA has completed */
+ if ( dma_pending ) {
+ ioctl(console_fd, PS2IOC_SENDQCT, 1);
+ dma_pending = 0;
+ }
+
+ /* If the mouse is visible, draw it on the DMA area */
+ if ( (SDL_cursorstate & CURSOR_VISIBLE) && !cursor_drawn ) {
+ this->screen->pixels = mapped_mem + this->screen->offset;
+ SDL_DrawCursorNoLock(this->screen);
+ this->screen->pixels = NULL;
+ cursor_drawn = 1;
+ }
+
+ /* Put the image onto the screen */
+ loadimage_nonblock(console_fd,
+ &screen_image, screen_image_size,
+ head_tags_mem, image_tags_mem);
+ if ( screen_image.y > 0 ) {
+ /* Need to scale offscreen image to TV output */
+ ioctl(console_fd, PS2IOC_SENDQCT, 1);
+ dma_pending = 0;
+ scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem);
+ } else {
+ dma_pending = 1;
+ }
+
+ /* We're finished! */
+ SDL_UnlockCursor();
+}
+
+static int GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ return(0);
+}
+
+static void GS_VideoQuit(_THIS)
+{
+ /* Close console and input file descriptors */
+ if ( console_fd > 0 ) {
+ /* Unmap the video framebuffer */
+ if ( mapped_mem ) {
+ /* Unmap the video framebuffer */
+ munmap(mapped_mem, mapped_len);
+ mapped_mem = NULL;
+ }
+ close(memory_fd);
+
+ /* Restore the original video mode */
+ if ( GS_InGraphicsMode(this) ) {
+ ioctl(console_fd, PS2IOC_SSCREENINFO, &saved_vinfo);
+ }
+
+ /* We're all done with the graphics device */
+ close(console_fd);
+ console_fd = -1;
+ }
+ GS_CloseMouse(this);
+ GS_CloseKeyboard(this);
+}
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.h b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.h
new file mode 100644
index 0000000..8972d70
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsvideo.h
@@ -0,0 +1,95 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_gsvideo_h
+#define _SDL_gsvideo_h
+
+#include <sys/types.h>
+#include <termios.h>
+#include <linux/ps2/dev.h>
+#include <linux/ps2/gs.h>
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ /* Gotta love that simple PS2 graphics interface. :) */
+ int console_fd;
+ int memory_fd;
+ struct ps2_screeninfo saved_vinfo;
+
+ /* Ye olde linux keyboard code */
+ int current_vt;
+ int saved_vt;
+ int keyboard_fd;
+ int saved_kbd_mode;
+ struct termios saved_kbd_termios;
+
+ /* Ye olde linux mouse code */
+ int mouse_fd;
+ int cursor_drawn;
+
+ /* The memory mapped DMA area and associated variables */
+ caddr_t mapped_mem;
+ int pixels_len;
+ int mapped_len;
+ struct ps2_image screen_image;
+ int screen_image_size;
+ unsigned long long *head_tags_mem;
+ unsigned long long *image_tags_mem;
+ unsigned long long *tex_tags_mem;
+ unsigned long long *scale_tags_mem;
+ int dma_pending;
+};
+/* Old variable names */
+#define console_fd (this->hidden->console_fd)
+#define memory_fd (this->hidden->memory_fd)
+#define saved_vinfo (this->hidden->saved_vinfo)
+#define current_vt (this->hidden->current_vt)
+#define saved_vt (this->hidden->saved_vt)
+#define keyboard_fd (this->hidden->keyboard_fd)
+#define saved_kbd_mode (this->hidden->saved_kbd_mode)
+#define saved_kbd_termios (this->hidden->saved_kbd_termios)
+#define mouse_fd (this->hidden->mouse_fd)
+#define cursor_drawn (this->hidden->cursor_drawn)
+#define mapped_mem (this->hidden->mapped_mem)
+#define pixels_len (this->hidden->pixels_len)
+#define mapped_len (this->hidden->mapped_len)
+#define screen_image (this->hidden->screen_image)
+#define screen_image_size (this->hidden->screen_image_size)
+#define head_tags_mem (this->hidden->head_tags_mem)
+#define image_tags_mem (this->hidden->image_tags_mem)
+#define tex_tags_mem (this->hidden->tex_tags_mem)
+#define scale_tags_mem (this->hidden->scale_tags_mem)
+#define dma_pending (this->hidden->dma_pending)
+
+/* Shared between the mouse and video code for screen update scaling */
+extern int scaleimage_nonblock(int fd,
+ unsigned long long *tm, unsigned long long *sm);
+#endif /* _SDL_gsvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv.c b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv.c
new file mode 100644
index 0000000..ec52a69
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv.c
@@ -0,0 +1,461 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the Playstation 2 implementation of YUV video overlays */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <asm/page.h> /* For definition of PAGE_SIZE */
+
+#include "SDL_video.h"
+#include "SDL_gsyuv_c.h"
+#include "../SDL_yuvfuncs.h"
+
+/* The maximum number of 16x16 pixel block converted at once */
+#define MAX_MACROBLOCKS 1024 /* 2^10 macroblocks at once */
+
+/* The functions used to manipulate video overlays */
+static struct private_yuvhwfuncs gs_yuvfuncs = {
+ GS_LockYUVOverlay,
+ GS_UnlockYUVOverlay,
+ GS_DisplayYUVOverlay,
+ GS_FreeYUVOverlay
+};
+
+struct private_yuvhwdata {
+ int ipu_fd;
+ Uint8 *pixels;
+ int macroblocks;
+ int dma_len;
+ caddr_t dma_mem;
+ caddr_t ipu_imem;
+ caddr_t ipu_omem;
+ caddr_t dma_tags;
+ unsigned long long *stretch_x1y1;
+ unsigned long long *stretch_x2y2;
+ struct ps2_plist plist;
+
+ /* These are just so we don't have to allocate them separately */
+ Uint16 pitches[3];
+ Uint8 *planes[3];
+};
+
+static int power_of_2(int value)
+{
+ int shift;
+
+ for ( shift = 0; (1<<shift) < value; ++shift ) {
+ /* Keep looking */ ;
+ }
+ return(shift);
+}
+
+SDL_Overlay *GS_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+ SDL_Overlay *overlay;
+ struct private_yuvhwdata *hwdata;
+ int map_offset;
+ unsigned long long *tags;
+ caddr_t base;
+ int bpp;
+ int fbp, fbw, psm;
+ int x, y, w, h;
+ int pnum;
+ struct ps2_packet *packet;
+ struct ps2_packet tex_packet;
+
+ /* We can only decode blocks of 16x16 pixels */
+ if ( (width & 15) || (height & 15) ) {
+ SDL_SetError("Overlay width/height must be multiples of 16");
+ return(NULL);
+ }
+ /* Make sure the image isn't too large for a single DMA transfer */
+ if ( ((width/16) * (height/16)) > MAX_MACROBLOCKS ) {
+ SDL_SetError("Overlay too large (maximum size: %d pixels)",
+ MAX_MACROBLOCKS * 16 * 16);
+ return(NULL);
+ }
+
+ /* Double-check the requested format. For simplicity, we'll only
+ support planar YUV formats.
+ */
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ /* Supported planar YUV format */
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format");
+ return(NULL);
+ }
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
+ if ( overlay == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(overlay, 0, (sizeof *overlay));
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &gs_yuvfuncs;
+ overlay->hw_overlay = 1;
+
+ /* Create the pixel data */
+ hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
+ overlay->hwdata = hwdata;
+ if ( hwdata == NULL ) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ hwdata->ipu_fd = -1;
+ hwdata->pixels = (Uint8 *)SDL_malloc(width*height*2);
+ if ( hwdata->pixels == NULL ) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ hwdata->macroblocks = (width/16) * (height/16);
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->pitches = hwdata->pitches;
+ overlay->pixels = hwdata->planes;
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ overlay->pitches[0] = overlay->w;
+ overlay->pitches[1] = overlay->pitches[0] / 2;
+ overlay->pitches[2] = overlay->pitches[0] / 2;
+ overlay->pixels[0] = hwdata->pixels;
+ overlay->pixels[1] = overlay->pixels[0] +
+ overlay->pitches[0] * overlay->h;
+ overlay->pixels[2] = overlay->pixels[1] +
+ overlay->pitches[1] * overlay->h / 2;
+ overlay->planes = 3;
+ break;
+ default:
+ /* We should never get here (caught above) */
+ break;
+ }
+
+ /* Theoretically we could support several concurrent decode
+ streams queueing up on the same file descriptor, but for
+ simplicity we'll support only one. Opening the IPU more
+ than once will fail with EBUSY.
+ */
+ hwdata->ipu_fd = open("/dev/ps2ipu", O_RDWR);
+ if ( hwdata->ipu_fd < 0 ) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_SetError("Playstation 2 IPU busy");
+ return(NULL);
+ }
+
+ /* Allocate a DMA area for pixel conversion */
+ bpp = this->screen->format->BytesPerPixel;
+ map_offset = (mapped_len + (sysconf(_SC_PAGESIZE) - 1)) & ~(sysconf(_SC_PAGESIZE) - 1);
+ hwdata->dma_len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8) +
+ width * height * bpp +
+ hwdata->macroblocks * (16 * sizeof(long long)) +
+ 12 * sizeof(long long);
+ hwdata->dma_mem = mmap(0, hwdata->dma_len, PROT_READ|PROT_WRITE,
+ MAP_SHARED, memory_fd, map_offset);
+ if ( hwdata->dma_mem == MAP_FAILED ) {
+ hwdata->ipu_imem = (caddr_t)0;
+ SDL_FreeYUVOverlay(overlay);
+ SDL_SetError("Unable to map %d bytes for DMA", hwdata->dma_len);
+ return(NULL);
+ }
+ hwdata->ipu_imem = hwdata->dma_mem;
+ hwdata->ipu_omem = hwdata->ipu_imem +
+ hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8);
+ hwdata->dma_tags = hwdata->ipu_omem + width * height * bpp;
+
+ /* Allocate memory for the DMA packets */
+ hwdata->plist.num = hwdata->macroblocks * 4 + 1;
+ hwdata->plist.packet = (struct ps2_packet *)SDL_malloc(
+ hwdata->plist.num*sizeof(struct ps2_packet));
+ if ( ! hwdata->plist.packet ) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ pnum = 0;
+ packet = hwdata->plist.packet;
+
+ /* Set up the tags to send the image to the screen */
+ tags = (unsigned long long *)hwdata->dma_tags;
+ base = hwdata->ipu_omem;
+ fbp = screen_image.fbp;
+ fbw = screen_image.fbw;
+ psm = screen_image.psm;
+ y = screen_image.y + screen_image.h; /* Offscreen video memory */
+ for ( h=height/16; h; --h ) {
+ x = 0; /* Visible video memory */
+ for ( w=width/16; w; --w ) {
+ /* The head tag */
+ packet[pnum].ptr = &tags[0];
+ packet[pnum].len = 10 * sizeof(*tags);
+ ++pnum;
+ tags[0] = 4 | (1LL << 60); /* GIFtag */
+ tags[1] = 0x0e; /* A+D */
+ tags[2] = ((unsigned long long)fbp << 32) |
+ ((unsigned long long)fbw << 48) |
+ ((unsigned long long)psm << 56);
+ tags[3] = PS2_GS_BITBLTBUF;
+ tags[4] = ((unsigned long long)x << 32) |
+ ((unsigned long long)y << 48);
+ tags[5] = PS2_GS_TRXPOS;
+ tags[6] = (unsigned long long)16 |
+ ((unsigned long long)16 << 32);
+ tags[7] = PS2_GS_TRXREG;
+ tags[8] = 0;
+ tags[9] = PS2_GS_TRXDIR;
+ /* Now the actual image data */
+ packet[pnum].ptr = &tags[10];
+ packet[pnum].len = 2 * sizeof(*tags);
+ ++pnum;
+ tags[10] = ((16*16*bpp) >> 4) | (2LL << 58);
+ tags[11] = 0;
+ packet[pnum].ptr = (void *)base;
+ packet[pnum].len = 16 * 16 * bpp;
+ ++pnum;
+ packet[pnum].ptr = &tags[12];
+ packet[pnum].len = 2 * sizeof(*tags);
+ ++pnum;
+ tags[12] = (0 >> 4) | (1 << 15) | (2LL << 58);
+ tags[13] = 0;
+
+ tags += 16;
+ base += 16 * 16 * bpp;
+
+ x += 16;
+ }
+ y += 16;
+ }
+
+ /* Set up the texture memory area for the video */
+ tex_packet.ptr = tags;
+ tex_packet.len = 8 * sizeof(*tags);
+ tags[0] = 3 | (1LL << 60); /* GIFtag */
+ tags[1] = 0x0e; /* A+D */
+ tags[2] = ((screen_image.y + screen_image.h) * screen_image.w) / 64 +
+ ((unsigned long long)fbw << 14) +
+ ((unsigned long long)psm << 20) +
+ ((unsigned long long)power_of_2(width) << 26) +
+ ((unsigned long long)power_of_2(height) << 30) +
+ ((unsigned long long)1 << 34) +
+ ((unsigned long long)1 << 35);
+ tags[3] = PS2_GS_TEX0_1;
+ tags[4] = (1 << 5) + (1 << 6);
+ tags[5] = PS2_GS_TEX1_1;
+ tags[6] = 0;
+ tags[7] = PS2_GS_TEXFLUSH;
+ ioctl(console_fd, PS2IOC_SEND, &tex_packet);
+
+ /* Set up the tags for scaling the image */
+ packet[pnum].ptr = tags;
+ packet[pnum].len = 12 * sizeof(*tags);
+ ++pnum;
+ tags[0] = 5 | (1LL << 60); /* GIFtag */
+ tags[1] = 0x0e; /* A+D */
+ tags[2] = 6 + (1 << 4) + (1 << 8);
+ tags[3] = PS2_GS_PRIM;
+ tags[4] = ((unsigned long long)0 * 16) +
+ (((unsigned long long)0 * 16) << 16);
+ tags[5] = PS2_GS_UV;
+ tags[6] = 0; /* X1, Y1 */
+ tags[7] = PS2_GS_XYZ2;
+ hwdata->stretch_x1y1 = &tags[6];
+ tags[8] = ((unsigned long long)overlay->w * 16) +
+ (((unsigned long long)overlay->h * 16) << 16);
+ tags[9] = PS2_GS_UV;
+ tags[10] = 0; /* X2, Y2 */
+ tags[11] = PS2_GS_XYZ2;
+ hwdata->stretch_x2y2 = &tags[10];
+
+ /* We're all done.. */
+ return(overlay);
+}
+
+int GS_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ return(0);
+}
+
+void GS_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ return;
+}
+
+int GS_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
+{
+ struct private_yuvhwdata *hwdata;
+ __u32 cmd;
+ struct ps2_packet packet;
+ int h, w, i;
+ Uint32 *lum, *Cr, *Cb;
+ int lum_pitch;
+ int crb_pitch;
+ Uint32 *lum_src, *Cr_src, *Cb_src;
+ Uint32 *srcp, *dstp;
+ unsigned int x, y;
+ SDL_Surface *screen;
+
+ /* Find out where the various portions of the image are */
+ hwdata = overlay->hwdata;
+ switch (overlay->format) {
+ case SDL_YV12_OVERLAY:
+ lum = (Uint32 *)overlay->pixels[0];
+ Cr = (Uint32 *)overlay->pixels[1];
+ Cb = (Uint32 *)overlay->pixels[2];
+ break;
+ case SDL_IYUV_OVERLAY:
+ lum = (Uint32 *)overlay->pixels[0];
+ Cr = (Uint32 *)overlay->pixels[2];
+ Cb = (Uint32 *)overlay->pixels[1];
+ default:
+ SDL_SetError("Unsupported YUV format in blit (?)");
+ return(-1);
+ }
+ dstp = (Uint32 *)hwdata->ipu_imem;
+ lum_pitch = overlay->w/4;
+ crb_pitch = (overlay->w/2)/4;
+
+ /* Copy blocks of 16x16 pixels to the DMA area */
+ for ( h=overlay->h/16; h; --h ) {
+ lum_src = lum;
+ Cr_src = Cr;
+ Cb_src = Cb;
+ for ( w=overlay->w/16; w; --w ) {
+ srcp = lum_src;
+ for ( i=0; i<16; ++i ) {
+ dstp[0] = srcp[0];
+ dstp[1] = srcp[1];
+ dstp[2] = srcp[2];
+ dstp[3] = srcp[3];
+ srcp += lum_pitch;
+ dstp += 4;
+ }
+ srcp = Cb_src;
+ for ( i=0; i<8; ++i ) {
+ dstp[0] = srcp[0];
+ dstp[1] = srcp[1];
+ srcp += crb_pitch;
+ dstp += 2;
+ }
+ srcp = Cr_src;
+ for ( i=0; i<8; ++i ) {
+ dstp[0] = srcp[0];
+ dstp[1] = srcp[1];
+ srcp += crb_pitch;
+ dstp += 2;
+ }
+ lum_src += 16 / 4;
+ Cb_src += 8 / 4;
+ Cr_src += 8 / 4;
+ }
+ lum += lum_pitch * 16;
+ Cr += crb_pitch * 8;
+ Cb += crb_pitch * 8;
+ }
+
+ /* Send the macroblock data to the IPU */
+#ifdef DEBUG_YUV
+ fprintf(stderr, "Sending data to IPU..\n");
+#endif
+ packet.ptr = hwdata->ipu_imem;
+ packet.len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8);
+ ioctl(hwdata->ipu_fd, PS2IOC_SENDA, &packet);
+
+ /* Trigger the DMA to the IPU for conversion */
+#ifdef DEBUG_YUV
+ fprintf(stderr, "Trigging conversion command\n");
+#endif
+ cmd = (7 << 28) + hwdata->macroblocks;
+ if ( screen_image.psm == PS2_GS_PSMCT16 ) {
+ cmd += (1 << 27) + /* Output RGB 555 */
+ (1 << 26); /* Dither output */
+ }
+ ioctl(hwdata->ipu_fd, PS2IOC_SIPUCMD, &cmd);
+
+ /* Retrieve the converted image from the IPU */
+#ifdef DEBUG_YUV
+ fprintf(stderr, "Retrieving data from IPU..\n");
+#endif
+ packet.ptr = hwdata->ipu_omem;
+ packet.len = overlay->w * overlay->h *
+ this->screen->format->BytesPerPixel;
+ ioctl(hwdata->ipu_fd, PS2IOC_RECV, &packet);
+
+#ifdef DEBUG_YUV
+ fprintf(stderr, "Copying image to screen..\n");
+#endif
+ /* Wait for previous DMA to complete */
+ ioctl(console_fd, PS2IOC_SENDQCT, 1);
+
+ /* Send the current image to the screen and scale it */
+ screen = this->screen;
+ x = (unsigned int)dst->x;
+ y = (unsigned int)dst->y;
+ if ( screen->offset ) {
+ x += (screen->offset % screen->pitch) /
+ screen->format->BytesPerPixel;
+ y += (screen->offset / screen->pitch);
+ }
+ y += screen_image.y;
+ *hwdata->stretch_x1y1 = (x * 16) + ((y * 16) << 16);
+ x += (unsigned int)dst->w;
+ y += (unsigned int)dst->h;
+ *hwdata->stretch_x2y2 = (x * 16) + ((y * 16) << 16);
+ return ioctl(console_fd, PS2IOC_SENDL, &hwdata->plist);
+}
+
+void GS_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ struct private_yuvhwdata *hwdata;
+
+ hwdata = overlay->hwdata;
+ if ( hwdata ) {
+ if ( hwdata->ipu_fd >= 0 ) {
+ close(hwdata->ipu_fd);
+ }
+ if ( hwdata->dma_mem ) {
+ munmap(hwdata->dma_mem, hwdata->dma_len);
+ }
+ if ( hwdata->plist.packet ) {
+ SDL_free(hwdata->plist.packet);
+ }
+ if ( hwdata->pixels ) {
+ SDL_free(hwdata->pixels);
+ }
+ SDL_free(hwdata);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv_c.h b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv_c.h
new file mode 100644
index 0000000..d9ffad6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps2gs/SDL_gsyuv_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the Playstation 2 implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_gsvideo.h"
+
+extern SDL_Overlay *GS_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int GS_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern void GS_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern int GS_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+
+extern void GS_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events.c b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events.c
new file mode 100644
index 0000000..e39efcc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events.c
@@ -0,0 +1,44 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ps3video.h"
+#include "SDL_ps3events_c.h"
+
+void PS3_PumpEvents(_THIS)
+{
+ return;
+}
+
+void PS3_InitOSKeymap(_THIS)
+{
+ return;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events_c.h b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events_c.h
new file mode 100644
index 0000000..fd11209
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3events_c.h
@@ -0,0 +1,41 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+
+#ifndef _SDL_ps3events_h
+#define _SDL_ps3events_h
+
+#include "SDL_ps3video.h"
+
+extern void PS3_InitOSKeymap(_THIS);
+extern void PS3_PumpEvents(_THIS);
+
+extern void enable_cursor(int enable);
+
+#endif /* _SDL_ps3events_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.c b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.c
new file mode 100644
index 0000000..d5519e0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.c
@@ -0,0 +1,621 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_ps3events_c.h"
+#include "SDL_ps3video.h"
+#include "SDL_ps3yuv_c.h"
+#include "spulibs/spu_common.h"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+#include <sys/mman.h>
+
+#include <linux/fb.h>
+#include <asm/ps3fb.h>
+#include <libspe2.h>
+#include <malloc.h>
+
+/* SDL_VideoDevice functions */
+static int PS3_Available();
+static SDL_VideoDevice *PS3_CreateDevice(int devindex);
+static int PS3_VideoInit(_THIS, SDL_PixelFormat * vformat);
+static void PS3_VideoQuit(_THIS);
+static void PS3_DeleteDevice(SDL_VideoDevice * device);
+static SDL_Surface *PS3_SetVideoMode(_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags);
+static SDL_Rect **PS3_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags);
+
+/* Hardware surface functions */
+static int PS3_AllocHWSurface(_THIS, SDL_Surface * surface);
+static void PS3_FreeHWSurface(_THIS, SDL_Surface * surface);
+static int PS3_LockHWSurface(_THIS, SDL_Surface * surface);
+static void PS3_UnlockHWSurface(_THIS, SDL_Surface * surface);
+static int PS3_FlipDoubleBuffer(_THIS, SDL_Surface * surface);
+static void PS3_DoubleBufferUpdate(_THIS, int numrects, SDL_Rect * rects);
+
+/* SPU specific functions */
+int SPE_Start(_THIS, spu_data_t * spe_data);
+int SPE_Stop(_THIS, spu_data_t * spe_data);
+int SPE_Boot(_THIS, spu_data_t * spe_data);
+int SPE_Shutdown(_THIS, spu_data_t * spe_data);
+int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
+int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
+void SPE_RunContext(void *thread_argp);
+
+/* Helpers */
+void enable_cursor(int enable);
+
+/* Stores the SPE executable name of fb_writer_spu */
+extern spe_program_handle_t fb_writer_spu;
+
+/* SDL PS3 bootstrap function for checking availability */
+static int PS3_Available()
+{
+ return 1;
+}
+
+/* SDL PS3 bootstrap function for creating the device */
+static SDL_VideoDevice *PS3_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *this;
+
+ /* Initialise SDL_VideoDevice */
+ this = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
+ if (this) {
+ memset(this, 0, sizeof *this);
+ this->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc(sizeof(struct SDL_PrivateVideoData));
+ }
+ /* Error handling */
+ if ((this == NULL) || (this->hidden == NULL)) {
+ SDL_OutOfMemory();
+ if (this)
+ SDL_free(this);
+ return 0;
+ }
+ memset(this->hidden, 0, sizeof(struct SDL_PrivateVideoData));
+
+ /* Set the function pointers */
+ this->VideoInit = PS3_VideoInit;
+ this->ListModes = PS3_ListModes;
+ this->SetVideoMode = PS3_SetVideoMode;
+ this->SetColors = 0;
+ this->CreateYUVOverlay = PS3_CreateYUVOverlay;
+ this->UpdateRects = 0;
+ this->VideoQuit = PS3_VideoQuit;
+ this->AllocHWSurface = PS3_AllocHWSurface;
+ this->CheckHWBlit = 0;
+ this->FillHWRect = 0;
+ this->SetHWColorKey = 0;
+ this->SetHWAlpha = 0;
+ this->LockHWSurface = PS3_LockHWSurface;
+ this->UnlockHWSurface = PS3_UnlockHWSurface;
+ this->FlipHWSurface = PS3_FlipDoubleBuffer;
+ this->FreeHWSurface = PS3_FreeHWSurface;
+ this->SetCaption = 0;
+ this->SetIcon = 0;
+ this->IconifyWindow = 0;
+ this->GrabInput = 0;
+ this->GetWMInfo = 0;
+ this->InitOSKeymap = PS3_InitOSKeymap;
+ this->PumpEvents = PS3_PumpEvents;
+
+ this->free = PS3_DeleteDevice;
+
+ return this;
+}
+
+
+/* Bootstraping (see SDL_sysvideo.h) */
+VideoBootStrap PS3_bootstrap = {
+ "ps3", "PS3 Cell SPU Driver",
+ PS3_Available, PS3_CreateDevice
+};
+
+
+/* Delete the device */
+static void PS3_DeleteDevice(SDL_VideoDevice * device)
+{
+ free(device->hidden);
+ free(device);
+}
+
+
+/* Initialise the PS3 video device */
+static int PS3_VideoInit(_THIS, SDL_PixelFormat * vformat)
+{
+ /* Hide the cursor */
+ enable_cursor(0);
+
+ /* Create SPU fb_parms and thread structure */
+ fb_parms = (struct fb_writer_parms_t *)
+ memalign(16, sizeof(struct fb_writer_parms_t));
+ fb_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
+ if (fb_parms == NULL || fb_thread_data == NULL) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ fb_thread_data->program = fb_writer_spu;
+ fb_thread_data->program_name = "fb_writer_spu";
+ fb_thread_data->argp = (void *)fb_parms;
+ fb_thread_data->keepalive = 1;
+ fb_thread_data->booted = 0;
+
+ SPE_Start(this, fb_thread_data);
+
+ /* Open the device */
+ fb_dev_fd = open(PS3_DEV_FB, O_RDWR);
+ if (fb_dev_fd < 0) {
+ SDL_SetError("[PS3] Unable to open device %s", PS3_DEV_FB);
+ return -1;
+ }
+
+ /* Get vscreeninfo */
+ if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
+ SDL_SetError("[PS3] Can't get VSCREENINFO");
+ if (fb_dev_fd >= 0)
+ close(fb_dev_fd);
+ fb_dev_fd = -1;
+ return -1;
+ }
+
+ /* Fill in our hardware acceleration capabilities */
+ this->info.current_w = fb_vinfo.xres;
+ this->info.current_h = fb_vinfo.yres;
+ this->info.wm_available = 0;
+ this->info.hw_available = 1;
+
+ /* Backup the original vinfo to restore later */
+ fb_orig_vinfo = fb_vinfo;
+
+ /* 16 and 15 bpp is reported as 16 bpp */
+ fb_bits_per_pixel = fb_vinfo.bits_per_pixel;
+ if (fb_bits_per_pixel == 16)
+ fb_bits_per_pixel =
+ fb_vinfo.red.length + fb_vinfo.green.length +
+ fb_vinfo.blue.length;
+
+ /* Set SDL_PixelFormat */
+ vformat->BitsPerPixel = fb_vinfo.bits_per_pixel;
+
+ fb_vinfo.xres_virtual = fb_vinfo.xres;
+ fb_vinfo.yres_virtual = fb_vinfo.yres;
+
+ /* Put vscreeninfo */
+ if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
+ SDL_SetError("[PS3] Can't put VSCREENINFO");
+ if (fb_dev_fd >= 0)
+ close(fb_dev_fd);
+ fb_dev_fd = -1;
+ return -1;
+ }
+
+ s_fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
+
+ s_writeable_width = fb_vinfo.xres;
+ s_writeable_height = fb_vinfo.yres;
+
+ /* Get ps3 screeninfo */
+ if (ioctl(fb_dev_fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0) {
+ SDL_SetError("[PS3] PS3FB_IOCTL_SCREENINFO failed");
+ }
+ deprintf(1, "[PS3] xres:%d yres:%d xoff:%d yoff:%d\n", res.xres, res.yres, res.xoff, res.yoff);
+
+ /* Only use double buffering if enough fb memory is available */
+ if (res.num_frames < 2) {
+ double_buffering = 0;
+ } else {
+ double_buffering = 1;
+ }
+
+ real_width = res.xres;
+ real_height = res.yres;
+
+ /*
+ * Take control of frame buffer from kernel, for details see
+ * http://felter.org/wesley/files/ps3/linux-20061110-docs/ApplicationProgrammingEnvironment.html
+ * kernel will no longer flip the screen itself
+ */
+ ioctl(fb_dev_fd, PS3FB_IOCTL_ON, 0);
+
+ /* Unblank screen */
+ ioctl(fb_dev_fd, FBIOBLANK, 0);
+
+ return 0;
+}
+
+
+/* List available PS3 resolutions */
+static SDL_Rect **PS3_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
+{
+ /* A list of video resolutions that we query for (sorted largest to
+ * smallest)
+ */
+ static SDL_Rect PS3_resolutions[] = {
+ {0, 0, 1920, 1080}, // 1080p 16:9 HD
+ {0, 0, 1600, 1200}, // WUXGA
+ {0, 0, 1280, 1024}, // SXGA
+ {0, 0, 1280, 720}, // 720p 16:9 HD
+ {0, 0, 1024, 768}, // WXGA
+ {0, 0, 1024, 576}, // 576p 16:9
+ {0, 0, 853, 480}, // 480p 16:9
+ {0, 0, 720, 576}, // 576p 4:3 (PAL)
+ {0, 0, 720, 480}, // 480p 16:9 (NTSC)
+ };
+ static SDL_Rect *PS3_modes[] = {
+ &PS3_resolutions[0],
+ &PS3_resolutions[1],
+ &PS3_resolutions[2],
+ &PS3_resolutions[3],
+ &PS3_resolutions[4],
+ &PS3_resolutions[5],
+ &PS3_resolutions[6],
+ &PS3_resolutions[7],
+ &PS3_resolutions[8],
+ NULL
+ };
+ SDL_Rect **modes = PS3_modes;
+
+ return modes;
+}
+
+
+/* Get a list of the available display modes */
+static SDL_Surface *PS3_SetVideoMode(_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags)
+{
+ s_bounded_input_width = width < s_writeable_width ? width : s_writeable_width;
+ s_bounded_input_height = height < s_writeable_height ? height : s_writeable_height;
+ s_bounded_input_width_offset = (s_writeable_width - s_bounded_input_width) >> 1;
+ s_bounded_input_height_offset = (s_writeable_height - s_bounded_input_height) >> 1;
+ s_input_line_length = width * s_fb_pixel_size;
+
+ current->flags |= flags;
+
+ if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
+ SDL_SetError("[PS3] Can't get fixed screeninfo");
+ return NULL;
+ }
+
+ if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) {
+ SDL_SetError("[PS3] type %s not supported",
+ fb_finfo.type);
+ return NULL;
+ }
+
+ /* Note: on PS3, fb_finfo.smem_len is enough for double buffering */
+ if ((frame_buffer =
+ (uint8_t *) mmap(0, fb_finfo.smem_len,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ fb_dev_fd, 0)) == (uint8_t *) - 1) {
+ SDL_SetError("[PS3] Can't mmap for %s", PS3_DEV_FB);
+ return NULL;
+ } else {
+ current->flags |= SDL_DOUBLEBUF;
+ }
+ if (!SDL_ReallocFormat(current, fb_bits_per_pixel, 0, 0, 0, 0)) {
+ return (NULL);
+ }
+
+ /* Blank screen */
+ memset(frame_buffer, 0x00, fb_finfo.smem_len);
+
+ /* Centering */
+ s_center[0] =
+ frame_buffer + s_bounded_input_width_offset * s_fb_pixel_size +
+ s_bounded_input_height_offset * fb_finfo.line_length;
+ s_center[1] = s_center[0] + real_height * fb_finfo.line_length;
+ s_center_index = 0;
+
+ current->flags |= SDL_FULLSCREEN;
+ current->w = width;
+ current->h = height;
+ current->pitch = SDL_CalculatePitch(current);
+
+ /* Alloc aligned mem for current->pixels */
+ s_pixels = memalign(16, current->h * current->pitch);
+ current->pixels = (void *)s_pixels;
+ if (!current->pixels) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+
+ /* Set the update rectangle function */
+ this->UpdateRects = PS3_DoubleBufferUpdate;
+
+ return current;
+}
+
+
+/* Copy screen to framebuffer and flip */
+void PS3_DoubleBufferUpdate(_THIS, int numrects, SDL_Rect * rects)
+{
+ if (converter_thread_data && converter_thread_data->booted)
+ SPE_WaitForMsg(this, converter_thread_data, SPU_FIN);
+
+ /* Adjust centering */
+ s_bounded_input_width_offset = (s_writeable_width - s_bounded_input_width) >> 1;
+ s_bounded_input_height_offset = (s_writeable_height - s_bounded_input_height) >> 1;
+ s_center[0] = frame_buffer + s_bounded_input_width_offset * s_fb_pixel_size +
+ s_bounded_input_height_offset * fb_finfo.line_length;
+ s_center[1] = s_center[0] + real_height * fb_finfo.line_length;
+
+ /* Set SPU parms for copying the surface to framebuffer */
+ fb_parms->data = (unsigned char *)s_pixels;
+ fb_parms->center = s_center[s_center_index];
+ fb_parms->out_line_stride = fb_finfo.line_length;
+ fb_parms->in_line_stride = s_input_line_length;
+ fb_parms->bounded_input_height = s_bounded_input_height;
+ fb_parms->bounded_input_width = s_bounded_input_width;
+ fb_parms->fb_pixel_size = s_fb_pixel_size;
+
+ deprintf(3, "[PS3->SPU] fb_thread_data->argp = 0x%x\n", fb_thread_data->argp);
+
+ /* Copying.. */
+ SPE_SendMsg(this, fb_thread_data, SPU_START);
+ SPE_SendMsg(this, fb_thread_data, (unsigned int)fb_thread_data->argp);
+
+ SPE_WaitForMsg(this, fb_thread_data, SPU_FIN);
+
+ /* Flip the pages */
+ if (double_buffering)
+ s_center_index = s_center_index ^ 0x01;
+ PS3_FlipDoubleBuffer(this, this->screen);
+}
+
+
+/* Enable/Disable cursor */
+void enable_cursor(int enable)
+{
+ int fd = open("/dev/console", O_RDWR | O_NONBLOCK);
+ if (fd >= 0) {
+ ioctl(fd, KDSETMODE, enable ? KD_TEXT : KD_GRAPHICS);
+ close(fd);
+ }
+}
+
+
+static int PS3_AllocHWSurface(_THIS, SDL_Surface * surface)
+{
+ return -1;
+}
+
+
+static void PS3_FreeHWSurface(_THIS, SDL_Surface * surface)
+{
+ return;
+}
+
+
+static int PS3_LockHWSurface(_THIS, SDL_Surface * surface)
+{
+ return 0;
+}
+
+
+static void PS3_UnlockHWSurface(_THIS, SDL_Surface * surface)
+{
+ return;
+}
+
+
+/* Blit/Flip buffer to the screen. Must be called after each frame! */
+int PS3_FlipDoubleBuffer(_THIS, SDL_Surface * surface)
+{
+ unsigned long crt = 0;
+ /* Wait for vsync */
+ deprintf(1, "[PS3] Wait for vsync\n");
+ ioctl(fb_dev_fd, FBIO_WAITFORVSYNC, &crt);
+ /* Page flip */
+ deprintf(1, "[PS3] Page flip to buffer #%u 0x%x\n", s_center_index, s_center[s_center_index]);
+ ioctl(fb_dev_fd, PS3FB_IOCTL_FSEL, (unsigned long)&s_center_index);
+ return 1;
+}
+
+
+/* Start the SPE thread */
+int SPE_Start(_THIS, spu_data_t * spe_data)
+{
+ deprintf(2, "[PS3->SPU] Start SPE: %s\n", spe_data->program_name);
+ if (!(spe_data->booted))
+ SPE_Boot(this, spe_data);
+
+ /* To allow re-running of context, spe_ctx_entry has to be set before each call */
+ spe_data->entry = SPE_DEFAULT_ENTRY;
+ spe_data->error_code = 0;
+
+ /* Create SPE thread and run */
+ deprintf(2, "[PS3->SPU] Create Thread: %s\n", spe_data->program_name);
+ if (pthread_create
+ (&spe_data->thread, NULL, (void *)&SPE_RunContext, (void *)spe_data)) {
+ deprintf(2, "[PS3->SPU] Could not create pthread for spe: %s\n", spe_data->program_name);
+ SDL_SetError("[PS3->SPU] Could not create pthread for spe");
+ return -1;
+ }
+
+ if (spe_data->keepalive)
+ SPE_WaitForMsg(this, spe_data, SPU_READY);
+}
+
+
+/* Stop the SPE thread */
+int SPE_Stop(_THIS, spu_data_t * spe_data)
+{
+ deprintf(2, "[PS3->SPU] Stop SPE: %s\n", spe_data->program_name);
+ /* Wait for SPE thread to complete */
+ deprintf(2, "[PS3->SPU] Wait for SPE thread to complete: %s\n", spe_data->program_name);
+ if (pthread_join(spe_data->thread, NULL)) {
+ deprintf(2, "[PS3->SPU] Failed joining the thread: %s\n", spe_data->program_name);
+ SDL_SetError("[PS3->SPU] Failed joining the thread");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* Create SPE context and load program */
+int SPE_Boot(_THIS, spu_data_t * spe_data)
+{
+ /* Create SPE context */
+ deprintf(2, "[PS3->SPU] Create SPE Context: %s\n", spe_data->program_name);
+ spe_data->ctx = spe_context_create(0, NULL);
+ if (spe_data->ctx == NULL) {
+ deprintf(2, "[PS3->SPU] Failed creating SPE context: %s\n", spe_data->program_name);
+ SDL_SetError("[PS3->SPU] Failed creating SPE context");
+ return -1;
+ }
+
+ /* Load SPE object into SPE local store */
+ deprintf(2, "[PS3->SPU] Load Program into SPE: %s\n", spe_data->program_name);
+ if (spe_program_load(spe_data->ctx, &spe_data->program)) {
+ deprintf(2, "[PS3->SPU] Failed loading program into SPE context: %s\n", spe_data->program_name);
+ SDL_SetError
+ ("[PS3->SPU] Failed loading program into SPE context");
+ return -1;
+ }
+ spe_data->booted = 1;
+ deprintf(2, "[PS3->SPU] SPE boot successful\n");
+
+ return 0;
+}
+
+/* (Stop and) shutdown the SPE */
+int SPE_Shutdown(_THIS, spu_data_t * spe_data)
+{
+ if (spe_data->keepalive && spe_data->booted) {
+ SPE_SendMsg(this, spe_data, SPU_EXIT);
+ SPE_Stop(this, spe_data);
+ }
+
+ /* Destroy SPE context */
+ deprintf(2, "[PS3->SPU] Destroy SPE context: %s\n", spe_data->program_name);
+ if (spe_context_destroy(spe_data->ctx)) {
+ deprintf(2, "[PS3->SPU] Failed destroying context: %s\n", spe_data->program_name);
+ SDL_SetError("[PS3->SPU] Failed destroying context");
+ return -1;
+ }
+ deprintf(2, "[PS3->SPU] SPE shutdown successful: %s\n", spe_data->program_name);
+ return 0;
+}
+
+
+/* Send message to the SPE via mailboxe */
+int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg)
+{
+ deprintf(2, "[PS3->SPU] Sending message %u to %s\n", msg, spe_data->program_name);
+ /* Send one message, block until message was sent */
+ unsigned int spe_in_mbox_msgs[1];
+ spe_in_mbox_msgs[0] = msg;
+ int in_mbox_write = spe_in_mbox_write(spe_data->ctx, spe_in_mbox_msgs, 1, SPE_MBOX_ALL_BLOCKING);
+
+ if (1 > in_mbox_write) {
+ deprintf(2, "[PS3->SPU] No message could be written to %s\n", spe_data->program_name);
+ SDL_SetError("[PS3->SPU] No message could be written");
+ return -1;
+ }
+ return 0;
+}
+
+
+/* Read 1 message from SPE, block until at least 1 message was received */
+int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg)
+{
+ deprintf(2, "[PS3->SPU] Waiting for message from %s\n", spe_data->program_name);
+ unsigned int out_messages[1];
+ while (!spe_out_mbox_status(spe_data->ctx));
+ int mbox_read = spe_out_mbox_read(spe_data->ctx, out_messages, 1);
+ deprintf(2, "[PS3->SPU] Got message from %s, message was %u\n", spe_data->program_name, out_messages[0]);
+ if (out_messages[0] == msg)
+ return 0;
+ else
+ return -1;
+}
+
+
+/* Re-runnable invocation of the spe_context_run call */
+void SPE_RunContext(void *thread_argp)
+{
+ /* argp is the pointer to argument to be passed to the SPE program */
+ spu_data_t *args = (spu_data_t *) thread_argp;
+ deprintf(3, "[PS3->SPU] void* argp=0x%x\n", (unsigned int)args->argp);
+
+ /* Run it.. */
+ deprintf(2, "[PS3->SPU] Run SPE program: %s\n", args->program_name);
+ if (spe_context_run
+ (args->ctx, &args->entry, 0, (void *)args->argp, NULL,
+ NULL) < 0) {
+ deprintf(2, "[PS3->SPU] Failed running SPE context: %s\n", args->program_name);
+ SDL_SetError("[PS3->SPU] Failed running SPE context: %s", args->program_name);
+ exit(1);
+ }
+
+ pthread_exit(NULL);
+}
+
+
+/* Quits the video driver */
+static void PS3_VideoQuit(_THIS)
+{
+ if (fb_dev_fd > 0) {
+ /* Restore the original video mode */
+ if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))
+ SDL_SetError("[PS3] Can't restore original fb_var_screeninfo");
+
+ /* Give control of frame buffer to kernel */
+ ioctl(fb_dev_fd, PS3FB_IOCTL_OFF, 0);
+ close(fb_dev_fd);
+ fb_dev_fd = -1;
+ }
+
+ if (frame_buffer) {
+ munmap(frame_buffer, fb_finfo.smem_len);
+ frame_buffer = 0;
+ }
+
+ if (fb_parms)
+ free((void *)fb_parms);
+ if (fb_thread_data) {
+ SPE_Shutdown(this, fb_thread_data);
+ free((void *)fb_thread_data);
+ }
+
+ if (this->screen) {
+ if (double_buffering && this->screen->pixels) {
+ free(this->screen->pixels);
+ }
+ this->screen->pixels = NULL;
+ }
+
+ enable_cursor(1);
+ deprintf(1, "[PS3] VideoQuit\n");
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.h b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.h
new file mode 100644
index 0000000..4fe5a2b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3video.h
@@ -0,0 +1,165 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "spulibs/spu_common.h"
+
+#include <libspe2.h>
+#include <pthread.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <asm/ps3fb.h>
+#include <linux/vt.h>
+#include <termios.h>
+
+#ifndef _SDL_ps3video_h
+#define _SDL_ps3video_h
+
+/* Debugging
+ * 0: No debug messages
+ * 1: Video debug messages
+ * 2: SPE debug messages
+ * 3: Memory adresses
+ */
+#define DEBUG_LEVEL 0
+
+#ifdef DEBUG_LEVEL
+#define deprintf( level, fmt, args... ) \
+ do \
+{ \
+ if ( (unsigned)(level) <= DEBUG_LEVEL ) \
+ { \
+ fprintf( stdout, fmt, ##args ); \
+ fflush( stdout ); \
+ } \
+} while ( 0 )
+#else
+#define deprintf( level, fmt, args... )
+#endif
+
+/* Framebuffer device */
+#define PS3_DEV_FB "/dev/fb0"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice * this
+
+/* SPU thread data */
+typedef struct spu_data {
+ spe_context_ptr_t ctx;
+ pthread_t thread;
+ spe_program_handle_t program;
+ char * program_name;
+ unsigned int booted;
+ unsigned int keepalive;
+ unsigned int entry;
+ int error_code;
+ void * argp;
+} spu_data_t;
+
+/* Private video driver data needed for Cell support */
+struct SDL_PrivateVideoData
+{
+ const char * const fb_dev_name; /* FB-device name */
+ int fb_dev_fd; /* Descriptor-handle for fb_dev_name */
+ uint8_t * frame_buffer; /* mmap'd access to fbdev */
+
+ /* SPE threading stuff */
+ spu_data_t * fb_thread_data;
+ spu_data_t * scaler_thread_data;
+ spu_data_t * converter_thread_data;
+
+ /* screeninfo (from linux/fb.h) */
+ struct fb_fix_screeninfo fb_finfo;
+ struct fb_var_screeninfo fb_vinfo;
+ struct fb_var_screeninfo fb_orig_vinfo;
+
+ /* screeninfo (from asm/ps3fb.h) */
+ struct ps3fb_ioctl_res res;
+
+ unsigned int double_buffering;
+ uint32_t real_width; // real width of screen
+ uint32_t real_height; // real height of screen
+
+ uint32_t s_fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
+ uint32_t fb_bits_per_pixel; // 32: 32 24: 24 16: 16 15: 15
+
+ uint32_t config_count;
+
+ uint32_t s_input_line_length; // precalculated: input_width * fb_pixel_size
+ uint32_t s_bounded_input_width; // width of input (bounded by writeable width)
+ uint32_t s_bounded_input_height;// height of input (bounded by writeable height)
+ uint32_t s_bounded_input_width_offset; // offset from the left side (used for centering)
+ uint32_t s_bounded_input_height_offset; // offset from the upper side (used for centering)
+ uint32_t s_writeable_width; // width of screen which is writeable
+ uint32_t s_writeable_height; // height of screen which is writeable
+
+ uint8_t * s_center[2]; // where to begin writing our image (centered?)
+ uint32_t s_center_index;
+
+ volatile void * s_pixels __attribute__((aligned(128)));
+
+ /* Framebuffer data */
+ volatile struct fb_writer_parms_t * fb_parms __attribute__((aligned(128)));
+};
+
+#define fb_dev_name (this->hidden->fb_dev_name)
+#define fb_dev_fd (this->hidden->fb_dev_fd)
+#define frame_buffer (this->hidden->frame_buffer)
+#define fb_thread_data (this->hidden->fb_thread_data)
+#define scaler_thread_data (this->hidden->scaler_thread_data)
+#define converter_thread_data (this->hidden->converter_thread_data)
+#define fb_parms (this->hidden->fb_parms)
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define SDL_videomode (this->hidden->SDL_videomode)
+#define fb_finfo (this->hidden->fb_finfo)
+#define fb_vinfo (this->hidden->fb_vinfo)
+#define fb_orig_vinfo (this->hidden->fb_orig_vinfo)
+#define res (this->hidden->res)
+#define double_buffering (this->hidden->double_buffering)
+#define real_width (this->hidden->real_width)
+#define real_height (this->hidden->real_height)
+#define s_fb_pixel_size (this->hidden->s_fb_pixel_size)
+#define fb_bits_per_pixel (this->hidden->fb_bits_per_pixel)
+#define config_count (this->hidden->config_count)
+#define s_input_line_length (this->hidden->s_input_line_length)
+#define s_bounded_input_width (this->hidden->s_bounded_input_width)
+#define s_bounded_input_height (this->hidden->s_bounded_input_height)
+#define s_bounded_input_width_offset (this->hidden->s_bounded_input_width_offset)
+#define s_bounded_input_height_offset (this->hidden->s_bounded_input_height_offset)
+#define s_writeable_width (this->hidden->s_writeable_width)
+#define s_writeable_height (this->hidden->s_writeable_height)
+#define s_center (this->hidden->s_center)
+#define s_center_index (this->hidden->s_center_index)
+#define s_pixels (this->hidden->s_pixels)
+
+#endif /* _SDL_ps3video_h */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv.c b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv.c
new file mode 100644
index 0000000..b1e17da
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv.c
@@ -0,0 +1,340 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "SDL_ps3video.h"
+#include "SDL_ps3yuv_c.h"
+#include "../SDL_yuvfuncs.h"
+#include "spulibs/spu_common.h"
+
+/* Stores the executable name */
+extern spe_program_handle_t yuv2rgb_spu;
+extern spe_program_handle_t bilin_scaler_spu;
+
+int SPE_Start(_THIS, spu_data_t * spe_data);
+int SPE_Stop(_THIS, spu_data_t * spe_data);
+int SPE_Boot(_THIS, spu_data_t * spe_data);
+int SPE_Shutdown(_THIS, spu_data_t * spe_data);
+int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
+int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
+void SPE_RunContext(void *thread_argp);
+
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs ps3_yuvfuncs = {
+ PS3_LockYUVOverlay,
+ PS3_UnlockYUVOverlay,
+ PS3_DisplayYUVOverlay,
+ PS3_FreeYUVOverlay
+};
+
+
+struct private_yuvhwdata {
+ SDL_Surface *display;
+ SDL_Surface *stretch;
+ volatile void * pixels __attribute__((aligned(128)));
+
+ /* These are just so we don't have to allocate them separately */
+ Uint16 pitches[3];
+ Uint8 * planes[3];
+
+ unsigned int scale;
+
+ /* Scaled YUV picture */
+ Uint8 * scaler_out __attribute__((aligned(128)));
+
+ /* YUV2RGB converter data */
+ volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128)));
+
+ /* Scaler data */
+ volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128)));
+
+ Uint8 locked;
+};
+
+
+SDL_Overlay *PS3_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
+ /* Only RGB packed pixel conversion supported */
+ if ((display->format->BytesPerPixel != 2) &&
+ (display->format->BytesPerPixel != 3) &&
+ (display->format->BytesPerPixel != 4))
+ {
+ SDL_SetError ("Can't use YUV data on non 16/24/32 bit surfaces");
+ return NULL;
+ }
+
+ /* Double-check the requested format. We'll only support YV12 */
+ switch (format) {
+ case SDL_IYUV_OVERLAY:
+ case SDL_YV12_OVERLAY:
+ /* Supported YUV format */
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format");
+ return NULL;
+ }
+
+ SDL_Overlay* overlay;
+ struct private_yuvhwdata* hwdata;
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay *) SDL_calloc(1, sizeof(SDL_Overlay));
+ if (overlay == NULL) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ SDL_memset(overlay, 0, (sizeof *overlay));
+
+ /* Set the basic attributes */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+ overlay->hwdata = NULL;
+
+ /* Set up the PS3 YUV surface function structure */
+ overlay->hwfuncs = &ps3_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = (struct private_yuvhwdata *) SDL_calloc(1, sizeof(struct private_yuvhwdata));
+ if (hwdata == NULL) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return NULL;
+ }
+ overlay->hwdata = hwdata;
+
+ hwdata->stretch = NULL;
+ hwdata->display = display;
+
+ /* Create SPU parms structure */
+ hwdata->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t));
+ hwdata->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t));
+ if (hwdata->converter_parms == NULL || hwdata->scaler_parms == NULL) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ /* Set up the SPEs */
+ scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
+ converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
+ if (converter_thread_data == NULL || scaler_thread_data == NULL) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ scaler_thread_data->program = bilin_scaler_spu;
+ scaler_thread_data->program_name = "bilin_scaler_spu";
+ scaler_thread_data->keepalive = 0;
+ scaler_thread_data->booted = 0;
+
+ converter_thread_data->program = yuv2rgb_spu;
+ converter_thread_data->program_name = "yuv2rgb_spu";
+ converter_thread_data->keepalive = 1;
+ converter_thread_data->booted = 0;
+
+ SPE_Start(this, converter_thread_data);
+
+ hwdata->pixels = (Uint8 *) memalign(16, width * height + ((width * height) >> 1));
+ if (hwdata->pixels == NULL) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->pitches = hwdata->pitches;
+ overlay->pixels = hwdata->planes;
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ overlay->pitches[0] = overlay->w;
+ overlay->pitches[1] = overlay->pitches[0] / 2;
+ overlay->pitches[2] = overlay->pitches[0] / 2;
+ overlay->pixels[0] = (Uint8 *)hwdata->pixels;
+ overlay->pixels[1] = overlay->pixels[0] +
+ overlay->pitches[0] * overlay->h;
+ overlay->pixels[2] = overlay->pixels[1] +
+ overlay->pitches[1] * overlay->h / 2;
+ overlay->planes = 3;
+ break;
+ default:
+ /* We should never get here (caught above) */
+ break;
+ }
+
+ /* We're all done.. */
+ return overlay;
+}
+
+
+int PS3_LockYUVOverlay(_THIS, SDL_Overlay *overlay) {
+ if (overlay == NULL) {
+ return -1;
+ }
+ overlay->hwdata->locked = 1;
+
+ return 0;
+}
+
+
+void PS3_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) {
+ if (overlay == NULL) {
+ return;
+ }
+ overlay->hwdata->locked = 0;
+
+ return;
+}
+
+
+int PS3_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) {
+ if ((overlay == NULL) || (overlay->hwdata == NULL)) {
+ return -1;
+ }
+
+ Uint8 *lum, *Cr, *Cb;
+ struct private_yuvhwdata *hwdata;
+ SDL_Surface *display;
+
+ hwdata = overlay->hwdata;
+ display = hwdata->display;
+
+ /* Do we have to scale? */
+ if ((src->w != dst->w) || (src->h != dst->h) ) {
+ hwdata->scale = 1;
+ deprintf(1, "[PS3] We need to scale\n");
+ } else {
+ hwdata->scale = 0;
+ deprintf(1, "[PS3] No scaling\n");
+ }
+
+ /* Find out where the various portions of the image are */
+ switch (overlay->format) {
+ case SDL_YV12_OVERLAY:
+ lum = (Uint8 *)overlay->pixels[0];
+ Cr = (Uint8 *)overlay->pixels[1];
+ Cb = (Uint8 *)overlay->pixels[2];
+ break;
+ case SDL_IYUV_OVERLAY:
+ lum = (Uint8 *)overlay->pixels[0];
+ Cr = (Uint8 *)overlay->pixels[2];
+ Cb = (Uint8 *)overlay->pixels[1];
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format in blit");
+ return -1;
+ }
+
+ if (hwdata->scale) {
+ /* Alloc mem for scaled YUV picture */
+ hwdata->scaler_out = (Uint8 *) memalign(16, dst->w * dst->h + ((dst->w * dst->h) >> 1));
+ if (hwdata->scaler_out == NULL) {
+ SDL_FreeYUVOverlay(overlay);
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ /* Set parms for scaling */
+ hwdata->scaler_parms->src_pixel_width = src->w;
+ hwdata->scaler_parms->src_pixel_height = src->h;
+ hwdata->scaler_parms->dst_pixel_width = dst->w;
+ hwdata->scaler_parms->dst_pixel_height = dst->h;
+ hwdata->scaler_parms->y_plane = lum;
+ hwdata->scaler_parms->v_plane = Cr;
+ hwdata->scaler_parms->u_plane = Cb;
+ hwdata->scaler_parms->dstBuffer = hwdata->scaler_out;
+ scaler_thread_data->argp = (void *)hwdata->scaler_parms;
+
+ /* Scale the YUV overlay to given size */
+ SPE_Start(this, scaler_thread_data);
+ SPE_Stop(this, scaler_thread_data);
+
+ /* Set parms for converting after scaling */
+ hwdata->converter_parms->y_plane = hwdata->scaler_out;
+ hwdata->converter_parms->v_plane = hwdata->scaler_out + dst->w * dst->h;
+ hwdata->converter_parms->u_plane = hwdata->scaler_out + dst->w * dst->h + ((dst->w * dst->h) >> 2);
+ } else {
+ /* Set parms for converting */
+ hwdata->converter_parms->y_plane = lum;
+ hwdata->converter_parms->v_plane = Cr;
+ hwdata->converter_parms->u_plane = Cb;
+ }
+
+ hwdata->converter_parms->src_pixel_width = dst->w;
+ hwdata->converter_parms->src_pixel_height = dst->h;
+ hwdata->converter_parms->dstBuffer = (Uint8 *) s_pixels;
+ converter_thread_data->argp = (void *)hwdata->converter_parms;
+
+ /* Convert YUV overlay to RGB */
+ SPE_SendMsg(this, converter_thread_data, SPU_START);
+ SPE_SendMsg(this, converter_thread_data, (unsigned int)converter_thread_data->argp);
+
+ /* Centering */
+ s_bounded_input_width = dst->w;
+ s_bounded_input_height = dst->h;
+
+ /* UpdateRects() will do the rest.. */
+ SDL_UpdateRects(display, 1, dst);
+
+ if (hwdata->scale)
+ SDL_free((void *)hwdata->scaler_out);
+
+ return 0;
+}
+
+
+void PS3_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) {
+ if (overlay == NULL) {
+ return;
+ }
+
+ if (overlay->hwdata == NULL) {
+ return;
+ }
+
+ struct private_yuvhwdata * hwdata;
+ hwdata = overlay->hwdata;
+
+ if (scaler_thread_data)
+ SDL_free(scaler_thread_data);
+ if (converter_thread_data) {
+ SPE_Shutdown(this, converter_thread_data);
+ SDL_free(converter_thread_data);
+ }
+
+ if (hwdata) {
+ if (hwdata->pixels)
+ SDL_free((void *)hwdata->pixels);
+ SDL_free(hwdata);
+ }
+ return;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv_c.h b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv_c.h
new file mode 100644
index 0000000..49f9d70
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/SDL_ps3yuv_c.h
@@ -0,0 +1,44 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "SDL_config.h"
+
+#ifndef _SDL_ps3yuv_h
+#define _SDL_ps3yuv_h
+
+/* This is the PS3 implementation of YUV video overlays */
+
+#include "SDL_video.h"
+
+extern SDL_Overlay *PS3_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+extern int PS3_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+extern int PS3_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+extern void PS3_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+extern void PS3_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+#endif /* _SDL_ps3yuv_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/spulibs/Makefile b/distrib/sdl-1.2.15/src/video/ps3/spulibs/Makefile
new file mode 100644
index 0000000..dc580d9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/spulibs/Makefile
@@ -0,0 +1,83 @@
+# This Makefile is for building the CELL BE SPU libs
+# libfb_writer_spu.so, libyuv2rgb_spu.so, libbilin_scaler_spu.so
+
+# Toolchain
+SPU_GCC=/usr/bin/spu-gcc
+PPU_GCC=/usr/bin/gcc
+PPU_EMBEDSPU=/usr/bin/embedspu
+PPU_AR=/usr/bin/ar
+PPU_LD=/usr/bin/ld
+INSTALL=/usr/bin/install
+
+SPU_CFLAGS=-W -Wall -Winline -Wno-main -I. -I /usr/spu/include -I /opt/cell/sdk/usr/spu/include -finline-limit=10000 -Winline -ftree-vectorize -funroll-loops -fmodulo-sched -ffast-math -fPIC -O2
+
+# Usually /usr/lib, depending on your distribution
+PREFIX=/usr/lib
+
+
+all: libfb_writer_spu.a libfb_writer_spu.so \
+ libyuv2rgb_spu.so libyuv2rgb_spu.a \
+ libbilin_scaler_spu.so libbilin_scaler_spu.a
+
+
+# fb_writer
+fb_writer_spu-embed.o: fb_writer.c spu_common.h
+ $(SPU_GCC) $(SPU_CFLAGS) -o fb_writer_spu fb_writer.c -lm
+ $(PPU_EMBEDSPU) -m32 fb_writer_spu fb_writer_spu fb_writer_spu-embed.o
+
+libfb_writer_spu.so: fb_writer_spu-embed.o
+ $(PPU_LD) -o libfb_writer_spu.so -shared -soname=libfb_writer_spu.so fb_writer_spu-embed.o
+
+libfb_writer_spu.a: fb_writer_spu-embed.o
+ $(PPU_AR) -qcs libfb_writer_spu.a fb_writer_spu-embed.o
+
+
+# yuv2rgb_converter
+yuv2rgb_spu-embed.o: yuv2rgb_converter.c spu_common.h
+ $(SPU_GCC) $(SPU_CFLAGS) -o yuv2rgb_spu yuv2rgb_converter.c -lm
+ $(PPU_EMBEDSPU) -m32 yuv2rgb_spu yuv2rgb_spu yuv2rgb_spu-embed.o
+
+libyuv2rgb_spu.a: yuv2rgb_spu-embed.o
+ $(PPU_AR) -qcs libyuv2rgb_spu.a yuv2rgb_spu-embed.o
+
+libyuv2rgb_spu.so: yuv2rgb_spu-embed.o
+ $(PPU_LD) -o libyuv2rgb_spu.so -shared -soname=libyuv2rgb_spu.so yuv2rgb_spu-embed.o
+
+
+# bilin_scaler
+bilin_scaler_spu-embed.o: bilin_scaler.c spu_common.h
+ $(SPU_GCC) $(SPU_CFLAGS) -o bilin_scaler_spu bilin_scaler.c -lm
+ $(PPU_EMBEDSPU) -m32 bilin_scaler_spu bilin_scaler_spu bilin_scaler_spu-embed.o
+
+libbilin_scaler_spu.a: bilin_scaler_spu-embed.o
+ $(PPU_AR) -qcs libbilin_scaler_spu.a bilin_scaler_spu-embed.o
+
+libbilin_scaler_spu.so: bilin_scaler_spu-embed.o
+ $(PPU_LD) -o libbilin_scaler_spu.so -shared -soname=libbilin_scaler_spu.so bilin_scaler_spu-embed.o
+
+install: libfb_writer_spu.a libfb_writer_spu.so \
+ libyuv2rgb_spu.so libyuv2rgb_spu.a \
+ libbilin_scaler_spu.so libbilin_scaler_spu.a
+ $(INSTALL) -c -m 0755 libfb_writer_spu.so $(PREFIX)/.
+ $(INSTALL) -c -m 0655 libfb_writer_spu.a $(PREFIX)/.
+ $(INSTALL) -c -m 0755 libyuv2rgb_spu.so $(PREFIX)/.
+ $(INSTALL) -c -m 0655 libyuv2rgb_spu.a $(PREFIX)/.
+ $(INSTALL) -c -m 0755 libbilin_scaler_spu.so $(PREFIX)/.
+ $(INSTALL) -c -m 0655 libbilin_scaler_spu.a $(PREFIX)/.
+
+
+uninstall: $(PREFIX)/libfb_writer_spu.so $(PREFIX)/libfb_writer_spu.a \
+ $(PREFIX)/libyuv2rgb_spu.so $(PREFIX)/libyuv2rgb_spu.a \
+ $(PREFIX)/libbilin_scaler_spu.so $(PREFIX)/libbilin_scaler_spu.a
+ rm -f $(PREFIX)/libfb_writer_spu.a
+ rm -f $(PREFIX)/libfb_writer_spu.so
+ rm -f $(PREFIX)/libyuv2rgb_spu.so
+ rm -f $(PREFIX)/libyuv2rgb_spu.a
+ rm -f $(PREFIX)/libbilin_scaler_spu.so
+ rm -f $(PREFIX)/libbilin_scaler_spu.a
+
+
+clean:
+ rm -f bilin_scaler_spu-embed.o libbilin_scaler_spu.so libbilin_scaler_spu.a bilin_scaler_spu
+ rm -f yuv2rgb_spu-embed.o libyuv2rgb_spu.so libyuv2rgb_spu.a yuv2rgb_spu
+ rm -f fb_writer_spu-embed.o libfb_writer_spu.so libfb_writer_spu.a fb_writer_spu
diff --git a/distrib/sdl-1.2.15/src/video/ps3/spulibs/bilin_scaler.c b/distrib/sdl-1.2.15/src/video/ps3/spulibs/bilin_scaler.c
new file mode 100644
index 0000000..be9b5c6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/spulibs/bilin_scaler.c
@@ -0,0 +1,2050 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "spu_common.h"
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+// Debugging
+//#define DEBUG
+
+#ifdef DEBUG
+#define deprintf(fmt, args... ) \
+ fprintf( stdout, fmt, ##args ); \
+ fflush( stdout );
+#else
+#define deprintf( fmt, args... )
+#endif
+
+struct scale_parms_t parms __attribute__((aligned(128)));
+
+/* A maximum of 8 lines Y, therefore 4 lines V, 4 lines U are stored
+ * there might be the need to retrieve misaligned data, adjust
+ * incoming v and u plane to be able to handle this (add 128)
+ */
+unsigned char y_plane[2][(MAX_HDTV_WIDTH+128)*4] __attribute__((aligned(128)));
+unsigned char v_plane[2][(MAX_HDTV_WIDTH+128)*2] __attribute__((aligned(128)));
+unsigned char u_plane[2][(MAX_HDTV_WIDTH+128)*2] __attribute__((aligned(128)));
+
+/* temp-buffer for scaling: 4 lines Y, therefore 2 lines V, 2 lines U */
+unsigned char scaled_y_plane[2][MAX_HDTV_WIDTH*2] __attribute__((aligned(128)));
+unsigned char scaled_v_plane[2][MAX_HDTV_WIDTH/2] __attribute__((aligned(128)));
+unsigned char scaled_u_plane[2][MAX_HDTV_WIDTH/2] __attribute__((aligned(128)));
+
+/* some vectors needed by the float to int conversion */
+static const vector float vec_255 = { 255.0f, 255.0f, 255.0f, 255.0f };
+static const vector float vec_0_1 = { 0.1f, 0.1f, 0.1f, 0.1f };
+
+void bilinear_scale_line_w8(unsigned char* src, unsigned char* dst_, unsigned int dst_width, vector float vf_x_scale, vector float vf_NSweight, unsigned int src_linestride);
+void bilinear_scale_line_w16(unsigned char* src, unsigned char* dst_, unsigned int dst_width, vector float vf_x_scale, vector float vf_NSweight, unsigned int src_linestride);
+
+void scale_srcw16_dstw16();
+void scale_srcw16_dstw32();
+void scale_srcw32_dstw16();
+void scale_srcw32_dstw32();
+
+int main( unsigned long long spe_id __attribute__((unused)), unsigned long long argp )
+{
+ deprintf("[SPU] bilin_scaler_spu is up... (on SPE #%llu)\n", spe_id);
+ /* DMA transfer for the input parameters */
+ spu_mfcdma32(&parms, (unsigned int)argp, sizeof(struct scale_parms_t), TAG_INIT, MFC_GET_CMD);
+ DMA_WAIT_TAG(TAG_INIT);
+
+ deprintf("[SPU] Scale %ux%u to %ux%u\n", parms.src_pixel_width, parms.src_pixel_height,
+ parms.dst_pixel_width, parms.dst_pixel_height);
+
+ if(parms.src_pixel_width & 0x1f) {
+ if(parms.dst_pixel_width & 0x1F) {
+ deprintf("[SPU] Using scale_srcw16_dstw16\n");
+ scale_srcw16_dstw16();
+ } else {
+ deprintf("[SPU] Using scale_srcw16_dstw32\n");
+ scale_srcw16_dstw32();
+ }
+ } else {
+ if(parms.dst_pixel_width & 0x1F) {
+ deprintf("[SPU] Using scale_srcw32_dstw16\n");
+ scale_srcw32_dstw16();
+ } else {
+ deprintf("[SPU] Using scale_srcw32_dstw32\n");
+ scale_srcw32_dstw32();
+ }
+ }
+ deprintf("[SPU] bilin_scaler_spu... done!\n");
+
+ return 0;
+}
+
+
+/*
+ * vfloat_to_vuint()
+ *
+ * converts a float vector to an unsinged int vector using saturated
+ * arithmetic
+ *
+ * @param vec_s float vector for conversion
+ * @returns converted unsigned int vector
+ */
+inline static vector unsigned int vfloat_to_vuint(vector float vec_s) {
+ vector unsigned int select_1 = spu_cmpgt(vec_0_1, vec_s);
+ vec_s = spu_sel(vec_s, vec_0_1, select_1);
+
+ vector unsigned int select_2 = spu_cmpgt(vec_s, vec_255);
+ vec_s = spu_sel(vec_s, vec_255, select_2);
+ return spu_convtu(vec_s,0);
+}
+
+
+/*
+ * scale_srcw16_dstw16()
+ *
+ * processes an input image of width 16
+ * scaling is done to a width 16
+ * result stored in RAM
+ */
+void scale_srcw16_dstw16() {
+ // extract parameters
+ unsigned char* dst_addr = (unsigned char *)parms.dstBuffer;
+
+ unsigned int src_width = parms.src_pixel_width;
+ unsigned int src_height = parms.src_pixel_height;
+ unsigned int dst_width = parms.dst_pixel_width;
+ unsigned int dst_height = parms.dst_pixel_height;
+
+ // YVU
+ unsigned int src_linestride_y = src_width;
+ unsigned int src_dbl_linestride_y = src_width<<1;
+ unsigned int src_linestride_vu = src_width>>1;
+ unsigned int src_dbl_linestride_vu = src_width;
+
+ // scaled YVU
+ unsigned int scaled_src_linestride_y = dst_width;
+
+ // ram addresses
+ unsigned char* src_addr_y = parms.y_plane;
+ unsigned char* src_addr_v = parms.v_plane;
+ unsigned char* src_addr_u = parms.u_plane;
+
+ // for handling misalignment, addresses are precalculated
+ unsigned char* precalc_src_addr_v = src_addr_v;
+ unsigned char* precalc_src_addr_u = src_addr_u;
+
+ unsigned int dst_picture_size = dst_width*dst_height;
+
+ // Sizes for destination
+ unsigned int dst_dbl_linestride_y = dst_width<<1;
+ unsigned int dst_dbl_linestride_vu = dst_width>>1;
+
+ // Perform address calculation for Y, V and U in main memory with dst_addr as base
+ unsigned char* dst_addr_main_memory_y = dst_addr;
+ unsigned char* dst_addr_main_memory_v = dst_addr + dst_picture_size;
+ unsigned char* dst_addr_main_memory_u = dst_addr_main_memory_v +(dst_picture_size>>2);
+
+ // calculate scale factors
+ vector float vf_x_scale = spu_splats( (float)src_width/(float)dst_width );
+ float y_scale = (float)src_height/(float)dst_height;
+
+ // double buffered processing
+ // buffer switching
+ unsigned int curr_src_idx = 0;
+ unsigned int curr_dst_idx = 0;
+ unsigned int next_src_idx, next_dst_idx;
+
+ // 2 lines y as output, upper and lowerline
+ unsigned int curr_interpl_y_upper = 0;
+ unsigned int next_interpl_y_upper;
+ unsigned int curr_interpl_y_lower, next_interpl_y_lower;
+ // only 1 line v/u output, both planes have the same dimension
+ unsigned int curr_interpl_vu = 0;
+ unsigned int next_interpl_vu;
+
+ // weights, calculated in every loop iteration
+ vector float vf_curr_NSweight_y_upper = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_y_upper;
+ vector float vf_curr_NSweight_y_lower, vf_next_NSweight_y_lower;
+ vector float vf_curr_NSweight_vu = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_vu;
+
+ // line indices for the src picture
+ float curr_src_y_upper = 0.0f, next_src_y_upper;
+ float curr_src_y_lower, next_src_y_lower;
+ float curr_src_vu = 0.0f, next_src_vu;
+
+ // line indices for the dst picture
+ unsigned int dst_y=0, dst_vu=0;
+
+ // offset for the v and u plane to handle misalignement
+ unsigned int curr_lsoff_v = 0, next_lsoff_v;
+ unsigned int curr_lsoff_u = 0, next_lsoff_u;
+
+ // calculate lower line indices
+ curr_src_y_lower = ((float)curr_interpl_y_upper+1)*y_scale;
+ curr_interpl_y_lower = (unsigned int)curr_src_y_lower;
+ // lower line weight
+ vf_curr_NSweight_y_lower = spu_splats( curr_src_y_lower-(float)curr_interpl_y_lower );
+
+
+ // start partially double buffered processing
+ // get initial data, 2 sets of y, 1 set v, 1 set u
+ mfc_get( y_plane[curr_src_idx], (unsigned int) src_addr_y, src_dbl_linestride_y, RETR_BUF, 0, 0 );
+ mfc_get( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(curr_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF,
+ 0, 0 );
+ mfc_get( v_plane[curr_src_idx], (unsigned int) src_addr_v, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+ mfc_get( u_plane[curr_src_idx], (unsigned int) src_addr_u, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+
+ /* iteration loop
+ * within each iteration 4 lines y, 2 lines v, 2 lines u are retrieved
+ * the scaled output is 2 lines y, 1 line v, 1 line u
+ * the yuv2rgb-converted output is stored to RAM
+ */
+ for( dst_vu=0; dst_vu<(dst_height>>1)-1; dst_vu++ ) {
+ dst_y = dst_vu<<1;
+
+ // calculate next indices
+ next_src_vu = ((float)dst_vu+1)*y_scale;
+ next_src_y_upper = ((float)dst_y+2)*y_scale;
+ next_src_y_lower = ((float)dst_y+3)*y_scale;
+
+ next_interpl_vu = (unsigned int) next_src_vu;
+ next_interpl_y_upper = (unsigned int) next_src_y_upper;
+ next_interpl_y_lower = (unsigned int) next_src_y_lower;
+
+ // calculate weight NORTH-SOUTH
+ vf_next_NSweight_vu = spu_splats( next_src_vu-(float)next_interpl_vu );
+ vf_next_NSweight_y_upper = spu_splats( next_src_y_upper-(float)next_interpl_y_upper );
+ vf_next_NSweight_y_lower = spu_splats( next_src_y_lower-(float)next_interpl_y_lower );
+
+ // get next lines
+ next_src_idx = curr_src_idx^1;
+ next_dst_idx = curr_dst_idx^1;
+
+ // 4 lines y
+ mfc_get( y_plane[next_src_idx],
+ (unsigned int) src_addr_y+(next_interpl_y_upper*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ mfc_get( y_plane[next_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(next_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ // 2 lines v
+ precalc_src_addr_v = src_addr_v+(next_interpl_vu*src_linestride_vu);
+ next_lsoff_v = ((unsigned int)precalc_src_addr_v)&0x0F;
+ mfc_get( v_plane[next_src_idx],
+ ((unsigned int) precalc_src_addr_v)&0xFFFFFFF0,
+ src_dbl_linestride_vu+(next_lsoff_v<<1),
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ // 2 lines u
+ precalc_src_addr_u = src_addr_u+(next_interpl_vu*src_linestride_vu);
+ next_lsoff_u = ((unsigned int)precalc_src_addr_u)&0x0F;
+ mfc_get( u_plane[next_src_idx],
+ ((unsigned int) precalc_src_addr_u)&0xFFFFFFF0,
+ src_dbl_linestride_vu+(next_lsoff_v<<1),
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w8( v_plane[curr_src_idx]+curr_lsoff_v,
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w8( u_plane[curr_src_idx]+curr_lsoff_u,
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+
+ // Store the result back to main memory into a destination buffer in YUV format
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+ //---------------------------------------------------------------------------------------------
+
+
+ // update for next cycle
+ curr_src_idx = next_src_idx;
+ curr_dst_idx = next_dst_idx;
+
+ curr_interpl_y_upper = next_interpl_y_upper;
+ curr_interpl_y_lower = next_interpl_y_lower;
+ curr_interpl_vu = next_interpl_vu;
+
+ vf_curr_NSweight_y_upper = vf_curr_NSweight_y_upper;
+ vf_curr_NSweight_y_lower = vf_curr_NSweight_y_lower;
+ vf_curr_NSweight_vu = vf_next_NSweight_vu;
+
+ curr_src_y_upper = next_src_y_upper;
+ curr_src_y_lower = next_src_y_lower;
+ curr_src_vu = next_src_vu;
+
+ curr_lsoff_v = next_lsoff_v;
+ curr_lsoff_u = next_lsoff_u;
+ }
+
+
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w8( v_plane[curr_src_idx]+curr_lsoff_v,
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w8( u_plane[curr_src_idx]+curr_lsoff_u,
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+
+ // Store the result back to main memory into a destination buffer in YUV format
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int)dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ // wait for completion
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+ //---------------------------------------------------------------------------------------------
+}
+
+
+/*
+ * scale_srcw16_dstw32()
+ *
+ * processes an input image of width 16
+ * scaling is done to a width 32
+ * yuv2rgb conversion on a width of 32
+ * result stored in RAM
+ */
+void scale_srcw16_dstw32() {
+ // extract parameters
+ unsigned char* dst_addr = (unsigned char *)parms.dstBuffer;
+
+ unsigned int src_width = parms.src_pixel_width;
+ unsigned int src_height = parms.src_pixel_height;
+ unsigned int dst_width = parms.dst_pixel_width;
+ unsigned int dst_height = parms.dst_pixel_height;
+
+ // YVU
+ unsigned int src_linestride_y = src_width;
+ unsigned int src_dbl_linestride_y = src_width<<1;
+ unsigned int src_linestride_vu = src_width>>1;
+ unsigned int src_dbl_linestride_vu = src_width;
+ // scaled YVU
+ unsigned int scaled_src_linestride_y = dst_width;
+
+ // ram addresses
+ unsigned char* src_addr_y = parms.y_plane;
+ unsigned char* src_addr_v = parms.v_plane;
+ unsigned char* src_addr_u = parms.u_plane;
+
+ unsigned int dst_picture_size = dst_width*dst_height;
+
+ // Sizes for destination
+ unsigned int dst_dbl_linestride_y = dst_width<<1;
+ unsigned int dst_dbl_linestride_vu = dst_width>>1;
+
+ // Perform address calculation for Y, V and U in main memory with dst_addr as base
+ unsigned char* dst_addr_main_memory_y = dst_addr;
+ unsigned char* dst_addr_main_memory_v = dst_addr + dst_picture_size;
+ unsigned char* dst_addr_main_memory_u = dst_addr_main_memory_v +(dst_picture_size>>2);
+
+
+ // for handling misalignment, addresses are precalculated
+ unsigned char* precalc_src_addr_v = src_addr_v;
+ unsigned char* precalc_src_addr_u = src_addr_u;
+
+ // calculate scale factors
+ vector float vf_x_scale = spu_splats( (float)src_width/(float)dst_width );
+ float y_scale = (float)src_height/(float)dst_height;
+
+ // double buffered processing
+ // buffer switching
+ unsigned int curr_src_idx = 0;
+ unsigned int curr_dst_idx = 0;
+ unsigned int next_src_idx, next_dst_idx;
+
+ // 2 lines y as output, upper and lowerline
+ unsigned int curr_interpl_y_upper = 0;
+ unsigned int next_interpl_y_upper;
+ unsigned int curr_interpl_y_lower, next_interpl_y_lower;
+ // only 1 line v/u output, both planes have the same dimension
+ unsigned int curr_interpl_vu = 0;
+ unsigned int next_interpl_vu;
+
+ // weights, calculated in every loop iteration
+ vector float vf_curr_NSweight_y_upper = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_y_upper;
+ vector float vf_curr_NSweight_y_lower, vf_next_NSweight_y_lower;
+ vector float vf_curr_NSweight_vu = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_vu;
+
+ // line indices for the src picture
+ float curr_src_y_upper = 0.0f, next_src_y_upper;
+ float curr_src_y_lower, next_src_y_lower;
+ float curr_src_vu = 0.0f, next_src_vu;
+
+ // line indices for the dst picture
+ unsigned int dst_y=0, dst_vu=0;
+
+ // offset for the v and u plane to handle misalignement
+ unsigned int curr_lsoff_v = 0, next_lsoff_v;
+ unsigned int curr_lsoff_u = 0, next_lsoff_u;
+
+ // calculate lower line idices
+ curr_src_y_lower = ((float)curr_interpl_y_upper+1)*y_scale;
+ curr_interpl_y_lower = (unsigned int)curr_src_y_lower;
+ // lower line weight
+ vf_curr_NSweight_y_lower = spu_splats( curr_src_y_lower-(float)curr_interpl_y_lower );
+
+
+ // start partially double buffered processing
+ // get initial data, 2 sets of y, 1 set v, 1 set u
+ mfc_get( y_plane[curr_src_idx], (unsigned int) src_addr_y, src_dbl_linestride_y, RETR_BUF, 0, 0 );
+ mfc_get( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(curr_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF,
+ 0, 0 );
+ mfc_get( v_plane[curr_src_idx], (unsigned int) src_addr_v, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+ mfc_get( u_plane[curr_src_idx], (unsigned int) src_addr_u, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+
+ // iteration loop
+ // within each iteration 4 lines y, 2 lines v, 2 lines u are retrieved
+ // the scaled output is 2 lines y, 1 line v, 1 line u
+ // the yuv2rgb-converted output is stored to RAM
+ for( dst_vu=0; dst_vu<(dst_height>>1)-1; dst_vu++ ) {
+ dst_y = dst_vu<<1;
+
+ // calculate next indices
+ next_src_vu = ((float)dst_vu+1)*y_scale;
+ next_src_y_upper = ((float)dst_y+2)*y_scale;
+ next_src_y_lower = ((float)dst_y+3)*y_scale;
+
+ next_interpl_vu = (unsigned int) next_src_vu;
+ next_interpl_y_upper = (unsigned int) next_src_y_upper;
+ next_interpl_y_lower = (unsigned int) next_src_y_lower;
+
+ // calculate weight NORTH-SOUTH
+ vf_next_NSweight_vu = spu_splats( next_src_vu-(float)next_interpl_vu );
+ vf_next_NSweight_y_upper = spu_splats( next_src_y_upper-(float)next_interpl_y_upper );
+ vf_next_NSweight_y_lower = spu_splats( next_src_y_lower-(float)next_interpl_y_lower );
+
+ // get next lines
+ next_src_idx = curr_src_idx^1;
+ next_dst_idx = curr_dst_idx^1;
+
+ // 4 lines y
+ mfc_get( y_plane[next_src_idx],
+ (unsigned int) src_addr_y+(next_interpl_y_upper*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ mfc_get( y_plane[next_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(next_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ // 2 lines v
+ precalc_src_addr_v = src_addr_v+(next_interpl_vu*src_linestride_vu);
+ next_lsoff_v = ((unsigned int)precalc_src_addr_v)&0x0F;
+ mfc_get( v_plane[next_src_idx],
+ ((unsigned int) precalc_src_addr_v)&0xFFFFFFF0,
+ src_dbl_linestride_vu+(next_lsoff_v<<1),
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ // 2 lines u
+ precalc_src_addr_u = src_addr_u+(next_interpl_vu*src_linestride_vu);
+ next_lsoff_u = ((unsigned int)precalc_src_addr_u)&0x0F;
+ mfc_get( u_plane[next_src_idx],
+ ((unsigned int) precalc_src_addr_u)&0xFFFFFFF0,
+ src_dbl_linestride_vu+(next_lsoff_v<<1),
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w8( v_plane[curr_src_idx]+curr_lsoff_v,
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w8( u_plane[curr_src_idx]+curr_lsoff_u,
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+ //---------------------------------------------------------------------------------------------
+
+
+ // update for next cycle
+ curr_src_idx = next_src_idx;
+ curr_dst_idx = next_dst_idx;
+
+ curr_interpl_y_upper = next_interpl_y_upper;
+ curr_interpl_y_lower = next_interpl_y_lower;
+ curr_interpl_vu = next_interpl_vu;
+
+ vf_curr_NSweight_y_upper = vf_curr_NSweight_y_upper;
+ vf_curr_NSweight_y_lower = vf_curr_NSweight_y_lower;
+ vf_curr_NSweight_vu = vf_next_NSweight_vu;
+
+ curr_src_y_upper = next_src_y_upper;
+ curr_src_y_lower = next_src_y_lower;
+ curr_src_vu = next_src_vu;
+
+ curr_lsoff_v = next_lsoff_v;
+ curr_lsoff_u = next_lsoff_u;
+ }
+
+
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w8( v_plane[curr_src_idx]+curr_lsoff_v,
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w8( u_plane[curr_src_idx]+curr_lsoff_u,
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ // wait for completion
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+ //---------------------------------------------------------------------------------------------
+}
+
+
+/*
+ * scale_srcw32_dstw16()
+ *
+ * processes an input image of width 32
+ * scaling is done to a width 16
+ * yuv2rgb conversion on a width of 16
+ * result stored in RAM
+ */
+void scale_srcw32_dstw16() {
+ // extract parameters
+ unsigned char* dst_addr = (unsigned char *)parms.dstBuffer;
+
+ unsigned int src_width = parms.src_pixel_width;
+ unsigned int src_height = parms.src_pixel_height;
+ unsigned int dst_width = parms.dst_pixel_width;
+ unsigned int dst_height = parms.dst_pixel_height;
+
+ // YVU
+ unsigned int src_linestride_y = src_width;
+ unsigned int src_dbl_linestride_y = src_width<<1;
+ unsigned int src_linestride_vu = src_width>>1;
+ unsigned int src_dbl_linestride_vu = src_width;
+ // scaled YVU
+ unsigned int scaled_src_linestride_y = dst_width;
+
+ // ram addresses
+ unsigned char* src_addr_y = parms.y_plane;
+ unsigned char* src_addr_v = parms.v_plane;
+ unsigned char* src_addr_u = parms.u_plane;
+
+ unsigned int dst_picture_size = dst_width*dst_height;
+
+ // Sizes for destination
+ unsigned int dst_dbl_linestride_y = dst_width<<1;
+ unsigned int dst_dbl_linestride_vu = dst_width>>1;
+
+ // Perform address calculation for Y, V and U in main memory with dst_addr as base
+ unsigned char* dst_addr_main_memory_y = dst_addr;
+ unsigned char* dst_addr_main_memory_v = dst_addr + dst_picture_size;
+ unsigned char* dst_addr_main_memory_u = dst_addr_main_memory_v +(dst_picture_size>>2);
+
+ // calculate scale factors
+ vector float vf_x_scale = spu_splats( (float)src_width/(float)dst_width );
+ float y_scale = (float)src_height/(float)dst_height;
+
+ // double buffered processing
+ // buffer switching
+ unsigned int curr_src_idx = 0;
+ unsigned int curr_dst_idx = 0;
+ unsigned int next_src_idx, next_dst_idx;
+
+ // 2 lines y as output, upper and lowerline
+ unsigned int curr_interpl_y_upper = 0;
+ unsigned int next_interpl_y_upper;
+ unsigned int curr_interpl_y_lower, next_interpl_y_lower;
+ // only 1 line v/u output, both planes have the same dimension
+ unsigned int curr_interpl_vu = 0;
+ unsigned int next_interpl_vu;
+
+ // weights, calculated in every loop iteration
+ vector float vf_curr_NSweight_y_upper = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_y_upper;
+ vector float vf_curr_NSweight_y_lower, vf_next_NSweight_y_lower;
+ vector float vf_curr_NSweight_vu = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_vu;
+
+ // line indices for the src picture
+ float curr_src_y_upper = 0.0f, next_src_y_upper;
+ float curr_src_y_lower, next_src_y_lower;
+ float curr_src_vu = 0.0f, next_src_vu;
+
+ // line indices for the dst picture
+ unsigned int dst_y=0, dst_vu=0;
+
+ // calculate lower line idices
+ curr_src_y_lower = ((float)curr_interpl_y_upper+1)*y_scale;
+ curr_interpl_y_lower = (unsigned int)curr_src_y_lower;
+ // lower line weight
+ vf_curr_NSweight_y_lower = spu_splats( curr_src_y_lower-(float)curr_interpl_y_lower );
+
+
+ // start partially double buffered processing
+ // get initial data, 2 sets of y, 1 set v, 1 set u
+ mfc_get( y_plane[curr_src_idx], (unsigned int) src_addr_y, src_dbl_linestride_y, RETR_BUF, 0, 0 );
+ mfc_get( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(curr_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF,
+ 0, 0 );
+ mfc_get( v_plane[curr_src_idx], (unsigned int) src_addr_v, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+ mfc_get( u_plane[curr_src_idx], (unsigned int) src_addr_u, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+
+ // iteration loop
+ // within each iteration 4 lines y, 2 lines v, 2 lines u are retrieved
+ // the scaled output is 2 lines y, 1 line v, 1 line u
+ // the yuv2rgb-converted output is stored to RAM
+ for( dst_vu=0; dst_vu<(dst_height>>1)-1; dst_vu++ ) {
+ dst_y = dst_vu<<1;
+
+ // calculate next indices
+ next_src_vu = ((float)dst_vu+1)*y_scale;
+ next_src_y_upper = ((float)dst_y+2)*y_scale;
+ next_src_y_lower = ((float)dst_y+3)*y_scale;
+
+ next_interpl_vu = (unsigned int) next_src_vu;
+ next_interpl_y_upper = (unsigned int) next_src_y_upper;
+ next_interpl_y_lower = (unsigned int) next_src_y_lower;
+
+ // calculate weight NORTH-SOUTH
+ vf_next_NSweight_vu = spu_splats( next_src_vu-(float)next_interpl_vu );
+ vf_next_NSweight_y_upper = spu_splats( next_src_y_upper-(float)next_interpl_y_upper );
+ vf_next_NSweight_y_lower = spu_splats( next_src_y_lower-(float)next_interpl_y_lower );
+
+ // get next lines
+ next_src_idx = curr_src_idx^1;
+ next_dst_idx = curr_dst_idx^1;
+
+ // 4 lines y
+ mfc_get( y_plane[next_src_idx],
+ (unsigned int) src_addr_y+(next_interpl_y_upper*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ mfc_get( y_plane[next_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(next_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ // 2 lines v
+ mfc_get( v_plane[next_src_idx],
+ (unsigned int) src_addr_v+(next_interpl_vu*src_linestride_vu),
+ src_dbl_linestride_vu,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ // 2 lines u
+ mfc_get( u_plane[next_src_idx],
+ (unsigned int) src_addr_u+(next_interpl_vu*src_linestride_vu),
+ src_dbl_linestride_vu,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w16( v_plane[curr_src_idx],
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w16( u_plane[curr_src_idx],
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+ //---------------------------------------------------------------------------------------------
+
+
+ // update for next cycle
+ curr_src_idx = next_src_idx;
+ curr_dst_idx = next_dst_idx;
+
+ curr_interpl_y_upper = next_interpl_y_upper;
+ curr_interpl_y_lower = next_interpl_y_lower;
+ curr_interpl_vu = next_interpl_vu;
+
+ vf_curr_NSweight_y_upper = vf_curr_NSweight_y_upper;
+ vf_curr_NSweight_y_lower = vf_curr_NSweight_y_lower;
+ vf_curr_NSweight_vu = vf_next_NSweight_vu;
+
+ curr_src_y_upper = next_src_y_upper;
+ curr_src_y_lower = next_src_y_lower;
+ curr_src_vu = next_src_vu;
+ }
+
+
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w16( v_plane[curr_src_idx],
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w16( u_plane[curr_src_idx],
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ // wait for completion
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+ //---------------------------------------------------------------------------------------------
+}
+
+
+/**
+ * scale_srcw32_dstw32()
+ *
+ * processes an input image of width 32
+ * scaling is done to a width 32
+ * yuv2rgb conversion on a width of 32
+ * result stored in RAM
+ */
+void scale_srcw32_dstw32() {
+ // extract parameters
+ unsigned char* dst_addr = (unsigned char *)parms.dstBuffer;
+
+ unsigned int src_width = parms.src_pixel_width;
+ unsigned int src_height = parms.src_pixel_height;
+ unsigned int dst_width = parms.dst_pixel_width;
+ unsigned int dst_height = parms.dst_pixel_height;
+
+ // YVU
+ unsigned int src_linestride_y = src_width;
+ unsigned int src_dbl_linestride_y = src_width<<1;
+ unsigned int src_linestride_vu = src_width>>1;
+ unsigned int src_dbl_linestride_vu = src_width;
+
+ // scaled YVU
+ unsigned int scaled_src_linestride_y = dst_width;
+
+ // ram addresses
+ unsigned char* src_addr_y = parms.y_plane;
+ unsigned char* src_addr_v = parms.v_plane;
+ unsigned char* src_addr_u = parms.u_plane;
+
+ unsigned int dst_picture_size = dst_width*dst_height;
+
+ // Sizes for destination
+ unsigned int dst_dbl_linestride_y = dst_width<<1;
+ unsigned int dst_dbl_linestride_vu = dst_width>>1;
+
+ // Perform address calculation for Y, V and U in main memory with dst_addr as base
+ unsigned char* dst_addr_main_memory_y = dst_addr;
+ unsigned char* dst_addr_main_memory_v = dst_addr + dst_picture_size;
+ unsigned char* dst_addr_main_memory_u = dst_addr_main_memory_v +(dst_picture_size>>2);
+
+ // calculate scale factors
+ vector float vf_x_scale = spu_splats( (float)src_width/(float)dst_width );
+ float y_scale = (float)src_height/(float)dst_height;
+
+ // double buffered processing
+ // buffer switching
+ unsigned int curr_src_idx = 0;
+ unsigned int curr_dst_idx = 0;
+ unsigned int next_src_idx, next_dst_idx;
+
+ // 2 lines y as output, upper and lowerline
+ unsigned int curr_interpl_y_upper = 0;
+ unsigned int next_interpl_y_upper;
+ unsigned int curr_interpl_y_lower, next_interpl_y_lower;
+ // only 1 line v/u output, both planes have the same dimension
+ unsigned int curr_interpl_vu = 0;
+ unsigned int next_interpl_vu;
+
+ // weights, calculated in every loop iteration
+ vector float vf_curr_NSweight_y_upper = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_y_upper;
+ vector float vf_curr_NSweight_y_lower, vf_next_NSweight_y_lower;
+ vector float vf_curr_NSweight_vu = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vector float vf_next_NSweight_vu;
+
+ // line indices for the src picture
+ float curr_src_y_upper = 0.0f, next_src_y_upper;
+ float curr_src_y_lower, next_src_y_lower;
+ float curr_src_vu = 0.0f, next_src_vu;
+
+ // line indices for the dst picture
+ unsigned int dst_y=0, dst_vu=0;
+
+ // calculate lower line idices
+ curr_src_y_lower = ((float)curr_interpl_y_upper+1)*y_scale;
+ curr_interpl_y_lower = (unsigned int)curr_src_y_lower;
+ // lower line weight
+ vf_curr_NSweight_y_lower = spu_splats( curr_src_y_lower-(float)curr_interpl_y_lower );
+
+
+ // start partially double buffered processing
+ // get initial data, 2 sets of y, 1 set v, 1 set u
+ mfc_get( y_plane[curr_src_idx], (unsigned int) src_addr_y, src_dbl_linestride_y, RETR_BUF, 0, 0 );
+ mfc_get( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(curr_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF,
+ 0, 0 );
+ mfc_get( v_plane[curr_src_idx], (unsigned int) src_addr_v, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+ mfc_get( u_plane[curr_src_idx], (unsigned int) src_addr_u, src_dbl_linestride_vu, RETR_BUF, 0, 0 );
+
+ // iteration loop
+ // within each iteration 4 lines y, 2 lines v, 2 lines u are retrieved
+ // the scaled output is 2 lines y, 1 line v, 1 line u
+ // the yuv2rgb-converted output is stored to RAM
+ for( dst_vu=0; dst_vu<(dst_height>>1)-1; dst_vu++ ) {
+ dst_y = dst_vu<<1;
+
+ // calculate next indices
+ next_src_vu = ((float)dst_vu+1)*y_scale;
+ next_src_y_upper = ((float)dst_y+2)*y_scale;
+ next_src_y_lower = ((float)dst_y+3)*y_scale;
+
+ next_interpl_vu = (unsigned int) next_src_vu;
+ next_interpl_y_upper = (unsigned int) next_src_y_upper;
+ next_interpl_y_lower = (unsigned int) next_src_y_lower;
+
+ // calculate weight NORTH-SOUTH
+ vf_next_NSweight_vu = spu_splats( next_src_vu-(float)next_interpl_vu );
+ vf_next_NSweight_y_upper = spu_splats( next_src_y_upper-(float)next_interpl_y_upper );
+ vf_next_NSweight_y_lower = spu_splats( next_src_y_lower-(float)next_interpl_y_lower );
+
+ // get next lines
+ next_src_idx = curr_src_idx^1;
+ next_dst_idx = curr_dst_idx^1;
+
+ // 4 lines y
+ mfc_get( y_plane[next_src_idx],
+ (unsigned int) src_addr_y+(next_interpl_y_upper*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ mfc_get( y_plane[next_src_idx]+src_dbl_linestride_y,
+ (unsigned int) src_addr_y+(next_interpl_y_lower*src_linestride_y),
+ src_dbl_linestride_y,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ // 2 lines v
+ mfc_get( v_plane[next_src_idx],
+ (unsigned int) src_addr_v+(next_interpl_vu*src_linestride_vu),
+ src_dbl_linestride_vu,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+ // 2 lines u
+ mfc_get( u_plane[next_src_idx],
+ (unsigned int) src_addr_u+(next_interpl_vu*src_linestride_vu),
+ src_dbl_linestride_vu,
+ RETR_BUF+next_src_idx,
+ 0, 0 );
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w16( v_plane[curr_src_idx],
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w16( u_plane[curr_src_idx],
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+
+
+ // Store the result back to main memory into a destination buffer in YUV format
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+ //---------------------------------------------------------------------------------------------
+
+
+ // update for next cycle
+ curr_src_idx = next_src_idx;
+ curr_dst_idx = next_dst_idx;
+
+ curr_interpl_y_upper = next_interpl_y_upper;
+ curr_interpl_y_lower = next_interpl_y_lower;
+ curr_interpl_vu = next_interpl_vu;
+
+ vf_curr_NSweight_y_upper = vf_curr_NSweight_y_upper;
+ vf_curr_NSweight_y_lower = vf_curr_NSweight_y_lower;
+ vf_curr_NSweight_vu = vf_next_NSweight_vu;
+
+ curr_src_y_upper = next_src_y_upper;
+ curr_src_y_lower = next_src_y_lower;
+ curr_src_vu = next_src_vu;
+ }
+
+
+
+ DMA_WAIT_TAG( (RETR_BUF+curr_src_idx) );
+
+ // scaling
+ // work line y_upper
+ bilinear_scale_line_w16( y_plane[curr_src_idx],
+ scaled_y_plane[curr_src_idx],
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_upper,
+ src_linestride_y );
+ // work line y_lower
+ bilinear_scale_line_w16( y_plane[curr_src_idx]+src_dbl_linestride_y,
+ scaled_y_plane[curr_src_idx]+scaled_src_linestride_y,
+ dst_width,
+ vf_x_scale,
+ vf_curr_NSweight_y_lower,
+ src_linestride_y );
+ // work line v
+ bilinear_scale_line_w16( v_plane[curr_src_idx],
+ scaled_v_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+ // work line u
+ bilinear_scale_line_w16( u_plane[curr_src_idx],
+ scaled_u_plane[curr_src_idx],
+ dst_width>>1,
+ vf_x_scale,
+ vf_curr_NSweight_vu,
+ src_linestride_vu );
+
+
+ // Store the result back to main memory into a destination buffer in YUV format
+ //---------------------------------------------------------------------------------------------
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+
+ // Perform three DMA transfers to 3 different locations in the main memory!
+ // dst_width: Pixel width of destination image
+ // dst_addr: Destination address in main memory
+ // dst_vu: Counter which is incremented one by one
+ // dst_y: Counter which is twice larger than dst_vu (dst_y = 2*dst_vu)
+
+ mfc_put( scaled_y_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_y + (dst_vu*dst_dbl_linestride_y), // Destination in main memory (addr)
+ dst_dbl_linestride_y, // Two Y lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_v_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_v + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two V lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ mfc_put( scaled_u_plane[curr_src_idx], // What from local store (addr)
+ (unsigned int) dst_addr_main_memory_u + (dst_vu*dst_dbl_linestride_vu), // Destination in main memory (addr)
+ dst_dbl_linestride_vu, // Two U lines (depending on the widht of the destination resolution)
+ STR_BUF+curr_dst_idx, // Tag
+ 0, 0 );
+
+ // wait for completion
+ DMA_WAIT_TAG( (STR_BUF+curr_dst_idx) );
+ //---------------------------------------------------------------------------------------------
+}
+
+
+/*
+ * bilinear_scale_line_w8()
+ *
+ * processes a line of yuv-input, width has to be a multiple of 8
+ * scaled yuv-output is written to local store buffer
+ *
+ * @param src buffer for 2 lines input
+ * @param dst_ buffer for 1 line output
+ * @param dst_width the width of the destination line
+ * @param vf_x_scale a float vector, at each entry is the x_scale-factor
+ * @param vf_NSweight a float vector, at each position is the weight NORTH/SOUTH for the current line
+ * @param src_linestride the stride of the srcline
+ */
+void bilinear_scale_line_w8( unsigned char* src, unsigned char* dst_, unsigned int dst_width, vector float vf_x_scale, vector float vf_NSweight, unsigned int src_linestride ) {
+
+ unsigned char* dst = dst_;
+
+ unsigned int dst_x;
+ for( dst_x=0; dst_x<dst_width; dst_x+=8) {
+ // address calculation for loading the 4 surrounding pixel of each calculated
+ // destination pixel
+ vector unsigned int vui_dst_x_tmp = spu_splats( dst_x );
+ // lower range->first 4 pixel
+ // upper range->next 4 pixel
+ vector unsigned int vui_inc_dst_x_lower_range = { 0, 1, 2, 3 };
+ vector unsigned int vui_inc_dst_x_upper_range = { 4, 5, 6, 7 };
+ vector unsigned int vui_dst_x_lower_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_lower_range );
+ vector unsigned int vui_dst_x_upper_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_upper_range );
+
+ // calculate weight EAST-WEST
+ vector float vf_dst_x_lower_range = spu_convtf( vui_dst_x_lower_range, 0 );
+ vector float vf_dst_x_upper_range = spu_convtf( vui_dst_x_upper_range, 0 );
+ vector float vf_src_x_lower_range = spu_mul( vf_dst_x_lower_range, vf_x_scale );
+ vector float vf_src_x_upper_range = spu_mul( vf_dst_x_upper_range, vf_x_scale );
+ vector unsigned int vui_interpl_x_lower_range = spu_convtu( vf_src_x_lower_range, 0 );
+ vector unsigned int vui_interpl_x_upper_range = spu_convtu( vf_src_x_upper_range, 0 );
+ vector float vf_interpl_x_lower_range = spu_convtf( vui_interpl_x_lower_range, 0 );
+ vector float vf_interpl_x_upper_range = spu_convtf( vui_interpl_x_upper_range, 0 );
+ vector float vf_EWweight_lower_range = spu_sub( vf_src_x_lower_range, vf_interpl_x_lower_range );
+ vector float vf_EWweight_upper_range = spu_sub( vf_src_x_upper_range, vf_interpl_x_upper_range );
+
+ // calculate address offset
+ //
+ // pixel NORTH WEST
+ vector unsigned int vui_off_pixelNW_lower_range = vui_interpl_x_lower_range;
+ vector unsigned int vui_off_pixelNW_upper_range = vui_interpl_x_upper_range;
+
+ // pixel NORTH EAST-->(offpixelNW+1)
+ vector unsigned int vui_add_1 = { 1, 1, 1, 1 };
+ vector unsigned int vui_off_pixelNE_lower_range = spu_add( vui_off_pixelNW_lower_range, vui_add_1 );
+ vector unsigned int vui_off_pixelNE_upper_range = spu_add( vui_off_pixelNW_upper_range, vui_add_1 );
+
+ // SOUTH-WEST-->(offpixelNW+src_linestride)
+ vector unsigned int vui_srclinestride = spu_splats( src_linestride );
+ vector unsigned int vui_off_pixelSW_lower_range = spu_add( vui_srclinestride, vui_off_pixelNW_lower_range );
+ vector unsigned int vui_off_pixelSW_upper_range = spu_add( vui_srclinestride, vui_off_pixelNW_upper_range );
+
+ // SOUTH-EAST-->(offpixelNW+src_linestride+1)
+ vector unsigned int vui_off_pixelSE_lower_range = spu_add( vui_srclinestride, vui_off_pixelNE_lower_range );
+ vector unsigned int vui_off_pixelSE_upper_range = spu_add( vui_srclinestride, vui_off_pixelNE_upper_range );
+
+ // calculate each address
+ vector unsigned int vui_src_ls = spu_splats( (unsigned int) src );
+ vector unsigned int vui_addr_pixelNW_lower_range = spu_add( vui_src_ls, vui_off_pixelNW_lower_range );
+ vector unsigned int vui_addr_pixelNW_upper_range = spu_add( vui_src_ls, vui_off_pixelNW_upper_range );
+ vector unsigned int vui_addr_pixelNE_lower_range = spu_add( vui_src_ls, vui_off_pixelNE_lower_range );
+ vector unsigned int vui_addr_pixelNE_upper_range = spu_add( vui_src_ls, vui_off_pixelNE_upper_range );
+
+ vector unsigned int vui_addr_pixelSW_lower_range = spu_add( vui_src_ls, vui_off_pixelSW_lower_range );
+ vector unsigned int vui_addr_pixelSW_upper_range = spu_add( vui_src_ls, vui_off_pixelSW_upper_range );
+ vector unsigned int vui_addr_pixelSE_lower_range = spu_add( vui_src_ls, vui_off_pixelSE_lower_range );
+ vector unsigned int vui_addr_pixelSE_upper_range = spu_add( vui_src_ls, vui_off_pixelSE_upper_range );
+
+ // get each pixel
+ //
+ // scalar load, afterwards insertion into the right position
+ // NORTH WEST
+ vector unsigned char null_vector = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ vector unsigned char vuc_pixel_NW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_lower_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_lower_range, 1 )),
+ vuc_pixel_NW_lower_range, 7 );
+ vuc_pixel_NW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_lower_range, 2 )),
+ vuc_pixel_NW_lower_range, 11 );
+ vuc_pixel_NW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_lower_range, 3 )),
+ vuc_pixel_NW_lower_range, 15 );
+
+ vector unsigned char vuc_pixel_NW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_upper_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_upper_range, 1 )),
+ vuc_pixel_NW_upper_range, 7 );
+ vuc_pixel_NW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_upper_range, 2 )),
+ vuc_pixel_NW_upper_range, 11 );
+ vuc_pixel_NW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_upper_range, 3 )),
+ vuc_pixel_NW_upper_range, 15 );
+
+ // NORTH EAST
+ vector unsigned char vuc_pixel_NE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_lower_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_lower_range, 1 )),
+ vuc_pixel_NE_lower_range, 7 );
+ vuc_pixel_NE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_lower_range, 2 )),
+ vuc_pixel_NE_lower_range, 11 );
+ vuc_pixel_NE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_lower_range, 3 )),
+ vuc_pixel_NE_lower_range, 15 );
+
+ vector unsigned char vuc_pixel_NE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_upper_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_upper_range, 1 )),
+ vuc_pixel_NE_upper_range, 7 );
+ vuc_pixel_NE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_upper_range, 2 )),
+ vuc_pixel_NE_upper_range, 11 );
+ vuc_pixel_NE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_upper_range, 3 )),
+ vuc_pixel_NE_upper_range, 15 );
+
+
+ // SOUTH WEST
+ vector unsigned char vuc_pixel_SW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_lower_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_lower_range, 1 )),
+ vuc_pixel_SW_lower_range, 7 );
+ vuc_pixel_SW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_lower_range, 2 )),
+ vuc_pixel_SW_lower_range, 11 );
+ vuc_pixel_SW_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_lower_range, 3 )),
+ vuc_pixel_SW_lower_range, 15 );
+
+ vector unsigned char vuc_pixel_SW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_upper_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_upper_range, 1 )),
+ vuc_pixel_SW_upper_range, 7 );
+ vuc_pixel_SW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_upper_range, 2 )),
+ vuc_pixel_SW_upper_range, 11 );
+ vuc_pixel_SW_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_upper_range, 3 )),
+ vuc_pixel_SW_upper_range, 15 );
+
+ // SOUTH EAST
+ vector unsigned char vuc_pixel_SE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_lower_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_lower_range, 1 )),
+ vuc_pixel_SE_lower_range, 7 );
+ vuc_pixel_SE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_lower_range, 2 )),
+ vuc_pixel_SE_lower_range, 11 );
+ vuc_pixel_SE_lower_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_lower_range, 3 )),
+ vuc_pixel_SE_lower_range, 15 );
+
+ vector unsigned char vuc_pixel_SE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_upper_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_upper_range, 1 )),
+ vuc_pixel_SE_upper_range, 7 );
+ vuc_pixel_SE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_upper_range, 2 )),
+ vuc_pixel_SE_upper_range, 11 );
+ vuc_pixel_SE_upper_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_upper_range, 3 )),
+ vuc_pixel_SE_upper_range, 15 );
+
+
+ // convert to float
+ vector float vf_pixel_NW_lower_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_lower_range, 0 );
+ vector float vf_pixel_NW_upper_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_upper_range, 0 );
+
+ vector float vf_pixel_SW_lower_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_lower_range, 0 );
+ vector float vf_pixel_SW_upper_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_upper_range, 0 );
+
+ vector float vf_pixel_NE_lower_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_lower_range, 0 );
+ vector float vf_pixel_NE_upper_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_upper_range, 0 );
+
+ vector float vf_pixel_SE_lower_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_lower_range, 0 );
+ vector float vf_pixel_SE_upper_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_upper_range, 0 );
+
+
+
+ // first linear interpolation: EWtop
+ // EWtop = NW + EWweight*(NE-NW)
+ //
+ // lower range
+ vector float vf_EWtop_lower_range_tmp = spu_sub( vf_pixel_NE_lower_range, vf_pixel_NW_lower_range );
+ vector float vf_EWtop_lower_range = spu_madd( vf_EWweight_lower_range,
+ vf_EWtop_lower_range_tmp,
+ vf_pixel_NW_lower_range );
+
+ // upper range
+ vector float vf_EWtop_upper_range_tmp = spu_sub( vf_pixel_NE_upper_range, vf_pixel_NW_upper_range );
+ vector float vf_EWtop_upper_range = spu_madd( vf_EWweight_upper_range,
+ vf_EWtop_upper_range_tmp,
+ vf_pixel_NW_upper_range );
+
+
+
+ // second linear interpolation: EWbottom
+ // EWbottom = SW + EWweight*(SE-SW)
+ //
+ // lower range
+ vector float vf_EWbottom_lower_range_tmp = spu_sub( vf_pixel_SE_lower_range, vf_pixel_SW_lower_range );
+ vector float vf_EWbottom_lower_range = spu_madd( vf_EWweight_lower_range,
+ vf_EWbottom_lower_range_tmp,
+ vf_pixel_SW_lower_range );
+
+ // upper range
+ vector float vf_EWbottom_upper_range_tmp = spu_sub( vf_pixel_SE_upper_range, vf_pixel_SW_upper_range );
+ vector float vf_EWbottom_upper_range = spu_madd( vf_EWweight_upper_range,
+ vf_EWbottom_upper_range_tmp,
+ vf_pixel_SW_upper_range );
+
+
+
+ // third linear interpolation: the bilinear interpolated value
+ // result = EWtop + NSweight*(EWbottom-EWtop);
+ //
+ // lower range
+ vector float vf_result_lower_range_tmp = spu_sub( vf_EWbottom_lower_range, vf_EWtop_lower_range );
+ vector float vf_result_lower_range = spu_madd( vf_NSweight,
+ vf_result_lower_range_tmp,
+ vf_EWtop_lower_range );
+
+ // upper range
+ vector float vf_result_upper_range_tmp = spu_sub( vf_EWbottom_upper_range, vf_EWtop_upper_range );
+ vector float vf_result_upper_range = spu_madd( vf_NSweight,
+ vf_result_upper_range_tmp,
+ vf_EWtop_upper_range );
+
+
+ // convert back: using saturated arithmetic
+ vector unsigned int vui_result_lower_range = vfloat_to_vuint( vf_result_lower_range );
+ vector unsigned int vui_result_upper_range = vfloat_to_vuint( vf_result_upper_range );
+
+ // merge results->lower,upper
+ vector unsigned char vuc_mask_merge_result = { 0x03, 0x07, 0x0B, 0x0F,
+ 0x13, 0x17, 0x1B, 0x1F,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+
+ vector unsigned char vuc_result = spu_shuffle( (vector unsigned char) vui_result_lower_range,
+ (vector unsigned char) vui_result_upper_range,
+ vuc_mask_merge_result );
+
+ // partial storing
+ vector unsigned char vuc_mask_out = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF };
+
+
+ // get currently stored data
+ vector unsigned char vuc_orig = *((vector unsigned char*)dst);
+
+ // clear currently stored data
+ vuc_orig = spu_and( vuc_orig,
+ spu_rlqwbyte( vuc_mask_out, ((unsigned int)dst)&0x0F) );
+
+ // rotate result according to storing address
+ vuc_result = spu_rlqwbyte( vuc_result, ((unsigned int)dst)&0x0F );
+
+ // store result
+ *((vector unsigned char*)dst) = spu_or( vuc_result,
+ vuc_orig );
+ dst += 8;
+ }
+}
+
+
+/*
+ * bilinear_scale_line_w16()
+ *
+ * processes a line of yuv-input, width has to be a multiple of 16
+ * scaled yuv-output is written to local store buffer
+ *
+ * @param src buffer for 2 lines input
+ * @param dst_ buffer for 1 line output
+ * @param dst_width the width of the destination line
+ * @param vf_x_scale a float vector, at each entry is the x_scale-factor
+ * @param vf_NSweight a float vector, at each position is the weight NORTH/SOUTH for the current line
+ * @param src_linestride the stride of the srcline
+ */
+void bilinear_scale_line_w16( unsigned char* src, unsigned char* dst_, unsigned int dst_width, vector float vf_x_scale, vector float vf_NSweight, unsigned int src_linestride ) {
+
+ unsigned char* dst = dst_;
+
+ unsigned int dst_x;
+ for( dst_x=0; dst_x<dst_width; dst_x+=16) {
+ // address calculation for loading the 4 surrounding pixel of each calculated
+ // destination pixel
+ vector unsigned int vui_dst_x_tmp = spu_splats( dst_x );
+ // parallelised processing
+ // first range->pixel 1 2 3 4
+ // second range->pixel 5 6 7 8
+ // third range->pixel 9 10 11 12
+ // fourth range->pixel 13 14 15 16
+ vector unsigned int vui_inc_dst_x_first_range = { 0, 1, 2, 3 };
+ vector unsigned int vui_inc_dst_x_second_range = { 4, 5, 6, 7 };
+ vector unsigned int vui_inc_dst_x_third_range = { 8, 9, 10, 11 };
+ vector unsigned int vui_inc_dst_x_fourth_range = { 12, 13, 14, 15 };
+ vector unsigned int vui_dst_x_first_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_first_range );
+ vector unsigned int vui_dst_x_second_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_second_range );
+ vector unsigned int vui_dst_x_third_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_third_range );
+ vector unsigned int vui_dst_x_fourth_range = spu_add( vui_dst_x_tmp, vui_inc_dst_x_fourth_range );
+
+ // calculate weight EAST-WEST
+ vector float vf_dst_x_first_range = spu_convtf( vui_dst_x_first_range, 0 );
+ vector float vf_dst_x_second_range = spu_convtf( vui_dst_x_second_range, 0 );
+ vector float vf_dst_x_third_range = spu_convtf( vui_dst_x_third_range, 0 );
+ vector float vf_dst_x_fourth_range = spu_convtf( vui_dst_x_fourth_range, 0 );
+ vector float vf_src_x_first_range = spu_mul( vf_dst_x_first_range, vf_x_scale );
+ vector float vf_src_x_second_range = spu_mul( vf_dst_x_second_range, vf_x_scale );
+ vector float vf_src_x_third_range = spu_mul( vf_dst_x_third_range, vf_x_scale );
+ vector float vf_src_x_fourth_range = spu_mul( vf_dst_x_fourth_range, vf_x_scale );
+ vector unsigned int vui_interpl_x_first_range = spu_convtu( vf_src_x_first_range, 0 );
+ vector unsigned int vui_interpl_x_second_range = spu_convtu( vf_src_x_second_range, 0 );
+ vector unsigned int vui_interpl_x_third_range = spu_convtu( vf_src_x_third_range, 0 );
+ vector unsigned int vui_interpl_x_fourth_range = spu_convtu( vf_src_x_fourth_range, 0 );
+ vector float vf_interpl_x_first_range = spu_convtf( vui_interpl_x_first_range, 0 );
+ vector float vf_interpl_x_second_range = spu_convtf( vui_interpl_x_second_range, 0 );
+ vector float vf_interpl_x_third_range = spu_convtf( vui_interpl_x_third_range, 0 );
+ vector float vf_interpl_x_fourth_range = spu_convtf( vui_interpl_x_fourth_range, 0 );
+ vector float vf_EWweight_first_range = spu_sub( vf_src_x_first_range, vf_interpl_x_first_range );
+ vector float vf_EWweight_second_range = spu_sub( vf_src_x_second_range, vf_interpl_x_second_range );
+ vector float vf_EWweight_third_range = spu_sub( vf_src_x_third_range, vf_interpl_x_third_range );
+ vector float vf_EWweight_fourth_range = spu_sub( vf_src_x_fourth_range, vf_interpl_x_fourth_range );
+
+ // calculate address offset
+ //
+ // pixel NORTH WEST
+ vector unsigned int vui_off_pixelNW_first_range = vui_interpl_x_first_range;
+ vector unsigned int vui_off_pixelNW_second_range = vui_interpl_x_second_range;
+ vector unsigned int vui_off_pixelNW_third_range = vui_interpl_x_third_range;
+ vector unsigned int vui_off_pixelNW_fourth_range = vui_interpl_x_fourth_range;
+
+ // pixel NORTH EAST-->(offpixelNW+1)
+ vector unsigned int vui_add_1 = { 1, 1, 1, 1 };
+ vector unsigned int vui_off_pixelNE_first_range = spu_add( vui_off_pixelNW_first_range, vui_add_1 );
+ vector unsigned int vui_off_pixelNE_second_range = spu_add( vui_off_pixelNW_second_range, vui_add_1 );
+ vector unsigned int vui_off_pixelNE_third_range = spu_add( vui_off_pixelNW_third_range, vui_add_1 );
+ vector unsigned int vui_off_pixelNE_fourth_range = spu_add( vui_off_pixelNW_fourth_range, vui_add_1 );
+
+ // SOUTH-WEST-->(offpixelNW+src_linestride)
+ vector unsigned int vui_srclinestride = spu_splats( src_linestride );
+ vector unsigned int vui_off_pixelSW_first_range = spu_add( vui_srclinestride, vui_off_pixelNW_first_range );
+ vector unsigned int vui_off_pixelSW_second_range = spu_add( vui_srclinestride, vui_off_pixelNW_second_range );
+ vector unsigned int vui_off_pixelSW_third_range = spu_add( vui_srclinestride, vui_off_pixelNW_third_range );
+ vector unsigned int vui_off_pixelSW_fourth_range = spu_add( vui_srclinestride, vui_off_pixelNW_fourth_range );
+
+ // SOUTH-EAST-->(offpixelNW+src_linestride+1)
+ vector unsigned int vui_off_pixelSE_first_range = spu_add( vui_srclinestride, vui_off_pixelNE_first_range );
+ vector unsigned int vui_off_pixelSE_second_range = spu_add( vui_srclinestride, vui_off_pixelNE_second_range );
+ vector unsigned int vui_off_pixelSE_third_range = spu_add( vui_srclinestride, vui_off_pixelNE_third_range );
+ vector unsigned int vui_off_pixelSE_fourth_range = spu_add( vui_srclinestride, vui_off_pixelNE_fourth_range );
+
+ // calculate each address
+ vector unsigned int vui_src_ls = spu_splats( (unsigned int) src );
+ vector unsigned int vui_addr_pixelNW_first_range = spu_add( vui_src_ls, vui_off_pixelNW_first_range );
+ vector unsigned int vui_addr_pixelNW_second_range = spu_add( vui_src_ls, vui_off_pixelNW_second_range );
+ vector unsigned int vui_addr_pixelNW_third_range = spu_add( vui_src_ls, vui_off_pixelNW_third_range );
+ vector unsigned int vui_addr_pixelNW_fourth_range = spu_add( vui_src_ls, vui_off_pixelNW_fourth_range );
+
+ vector unsigned int vui_addr_pixelNE_first_range = spu_add( vui_src_ls, vui_off_pixelNE_first_range );
+ vector unsigned int vui_addr_pixelNE_second_range = spu_add( vui_src_ls, vui_off_pixelNE_second_range );
+ vector unsigned int vui_addr_pixelNE_third_range = spu_add( vui_src_ls, vui_off_pixelNE_third_range );
+ vector unsigned int vui_addr_pixelNE_fourth_range = spu_add( vui_src_ls, vui_off_pixelNE_fourth_range );
+
+ vector unsigned int vui_addr_pixelSW_first_range = spu_add( vui_src_ls, vui_off_pixelSW_first_range );
+ vector unsigned int vui_addr_pixelSW_second_range = spu_add( vui_src_ls, vui_off_pixelSW_second_range );
+ vector unsigned int vui_addr_pixelSW_third_range = spu_add( vui_src_ls, vui_off_pixelSW_third_range );
+ vector unsigned int vui_addr_pixelSW_fourth_range = spu_add( vui_src_ls, vui_off_pixelSW_fourth_range );
+
+ vector unsigned int vui_addr_pixelSE_first_range = spu_add( vui_src_ls, vui_off_pixelSE_first_range );
+ vector unsigned int vui_addr_pixelSE_second_range = spu_add( vui_src_ls, vui_off_pixelSE_second_range );
+ vector unsigned int vui_addr_pixelSE_third_range = spu_add( vui_src_ls, vui_off_pixelSE_third_range );
+ vector unsigned int vui_addr_pixelSE_fourth_range = spu_add( vui_src_ls, vui_off_pixelSE_fourth_range );
+
+
+ // get each pixel
+ //
+ // scalar load, afterwards insertion into the right position
+ // NORTH WEST
+ // first range
+ vector unsigned char null_vector = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ vector unsigned char vuc_pixel_NW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_first_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_first_range, 1 )),
+ vuc_pixel_NW_first_range, 7 );
+ vuc_pixel_NW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_first_range, 2 )),
+ vuc_pixel_NW_first_range, 11 );
+ vuc_pixel_NW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_first_range, 3 )),
+ vuc_pixel_NW_first_range, 15 );
+ // second range
+ vector unsigned char vuc_pixel_NW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_second_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_second_range, 1 )),
+ vuc_pixel_NW_second_range, 7 );
+ vuc_pixel_NW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_second_range, 2 )),
+ vuc_pixel_NW_second_range, 11 );
+ vuc_pixel_NW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_second_range, 3 )),
+ vuc_pixel_NW_second_range, 15 );
+ // third range
+ vector unsigned char vuc_pixel_NW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_third_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_third_range, 1 )),
+ vuc_pixel_NW_third_range, 7 );
+ vuc_pixel_NW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_third_range, 2 )),
+ vuc_pixel_NW_third_range, 11 );
+ vuc_pixel_NW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_third_range, 3 )),
+ vuc_pixel_NW_third_range, 15 );
+ // fourth range
+ vector unsigned char vuc_pixel_NW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_fourth_range, 0 )), null_vector, 3 );
+ vuc_pixel_NW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_fourth_range, 1 )),
+ vuc_pixel_NW_fourth_range, 7 );
+ vuc_pixel_NW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_fourth_range, 2 )),
+ vuc_pixel_NW_fourth_range, 11 );
+ vuc_pixel_NW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNW_fourth_range, 3 )),
+ vuc_pixel_NW_fourth_range, 15 );
+
+ // NORTH EAST
+ // first range
+ vector unsigned char vuc_pixel_NE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_first_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_first_range, 1 )),
+ vuc_pixel_NE_first_range, 7 );
+ vuc_pixel_NE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_first_range, 2 )),
+ vuc_pixel_NE_first_range, 11 );
+ vuc_pixel_NE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_first_range, 3 )),
+ vuc_pixel_NE_first_range, 15 );
+ // second range
+ vector unsigned char vuc_pixel_NE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_second_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_second_range, 1 )),
+ vuc_pixel_NE_second_range, 7 );
+ vuc_pixel_NE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_second_range, 2 )),
+ vuc_pixel_NE_second_range, 11 );
+ vuc_pixel_NE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_second_range, 3 )),
+ vuc_pixel_NE_second_range, 15 );
+ // third range
+ vector unsigned char vuc_pixel_NE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_third_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_third_range, 1 )),
+ vuc_pixel_NE_third_range, 7 );
+ vuc_pixel_NE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_third_range, 2 )),
+ vuc_pixel_NE_third_range, 11 );
+ vuc_pixel_NE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_third_range, 3 )),
+ vuc_pixel_NE_third_range, 15 );
+ // fourth range
+ vector unsigned char vuc_pixel_NE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_fourth_range, 0 )), null_vector, 3 );
+ vuc_pixel_NE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_fourth_range, 1 )),
+ vuc_pixel_NE_fourth_range, 7 );
+ vuc_pixel_NE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_fourth_range, 2 )),
+ vuc_pixel_NE_fourth_range, 11 );
+ vuc_pixel_NE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelNE_fourth_range, 3 )),
+ vuc_pixel_NE_fourth_range, 15 );
+
+ // SOUTH WEST
+ // first range
+ vector unsigned char vuc_pixel_SW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_first_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_first_range, 1 )),
+ vuc_pixel_SW_first_range, 7 );
+ vuc_pixel_SW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_first_range, 2 )),
+ vuc_pixel_SW_first_range, 11 );
+ vuc_pixel_SW_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_first_range, 3 )),
+ vuc_pixel_SW_first_range, 15 );
+ // second range
+ vector unsigned char vuc_pixel_SW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_second_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_second_range, 1 )),
+ vuc_pixel_SW_second_range, 7 );
+ vuc_pixel_SW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_second_range, 2 )),
+ vuc_pixel_SW_second_range, 11 );
+ vuc_pixel_SW_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_second_range, 3 )),
+ vuc_pixel_SW_second_range, 15 );
+ // third range
+ vector unsigned char vuc_pixel_SW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_third_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_third_range, 1 )),
+ vuc_pixel_SW_third_range, 7 );
+ vuc_pixel_SW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_third_range, 2 )),
+ vuc_pixel_SW_third_range, 11 );
+ vuc_pixel_SW_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_third_range, 3 )),
+ vuc_pixel_SW_third_range, 15 );
+ // fourth range
+ vector unsigned char vuc_pixel_SW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_fourth_range, 0 )), null_vector, 3 );
+ vuc_pixel_SW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_fourth_range, 1 )),
+ vuc_pixel_SW_fourth_range, 7 );
+ vuc_pixel_SW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_fourth_range, 2 )),
+ vuc_pixel_SW_fourth_range, 11 );
+ vuc_pixel_SW_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSW_fourth_range, 3 )),
+ vuc_pixel_SW_fourth_range, 15 );
+
+ // NORTH EAST
+ // first range
+ vector unsigned char vuc_pixel_SE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_first_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_first_range, 1 )),
+ vuc_pixel_SE_first_range, 7 );
+ vuc_pixel_SE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_first_range, 2 )),
+ vuc_pixel_SE_first_range, 11 );
+ vuc_pixel_SE_first_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_first_range, 3 )),
+ vuc_pixel_SE_first_range, 15 );
+ // second range
+ vector unsigned char vuc_pixel_SE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_second_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_second_range, 1 )),
+ vuc_pixel_SE_second_range, 7 );
+ vuc_pixel_SE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_second_range, 2 )),
+ vuc_pixel_SE_second_range, 11 );
+ vuc_pixel_SE_second_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_second_range, 3 )),
+ vuc_pixel_SE_second_range, 15 );
+ // third range
+ vector unsigned char vuc_pixel_SE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_third_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_third_range, 1 )),
+ vuc_pixel_SE_third_range, 7 );
+ vuc_pixel_SE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_third_range, 2 )),
+ vuc_pixel_SE_third_range, 11 );
+ vuc_pixel_SE_third_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_third_range, 3 )),
+ vuc_pixel_SE_third_range, 15 );
+ // fourth range
+ vector unsigned char vuc_pixel_SE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_fourth_range, 0 )), null_vector, 3 );
+ vuc_pixel_SE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_fourth_range, 1 )),
+ vuc_pixel_SE_fourth_range, 7 );
+ vuc_pixel_SE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_fourth_range, 2 )),
+ vuc_pixel_SE_fourth_range, 11 );
+ vuc_pixel_SE_fourth_range = spu_insert(
+ *((unsigned char*) spu_extract( vui_addr_pixelSE_fourth_range, 3 )),
+ vuc_pixel_SE_fourth_range, 15 );
+
+
+
+ // convert to float
+ vector float vf_pixel_NW_first_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_first_range, 0 );
+ vector float vf_pixel_NW_second_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_second_range, 0 );
+ vector float vf_pixel_NW_third_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_third_range, 0 );
+ vector float vf_pixel_NW_fourth_range = spu_convtf( (vector unsigned int) vuc_pixel_NW_fourth_range, 0 );
+
+ vector float vf_pixel_NE_first_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_first_range, 0 );
+ vector float vf_pixel_NE_second_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_second_range, 0 );
+ vector float vf_pixel_NE_third_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_third_range, 0 );
+ vector float vf_pixel_NE_fourth_range = spu_convtf( (vector unsigned int) vuc_pixel_NE_fourth_range, 0 );
+
+ vector float vf_pixel_SW_first_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_first_range, 0 );
+ vector float vf_pixel_SW_second_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_second_range, 0 );
+ vector float vf_pixel_SW_third_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_third_range, 0 );
+ vector float vf_pixel_SW_fourth_range = spu_convtf( (vector unsigned int) vuc_pixel_SW_fourth_range, 0 );
+
+ vector float vf_pixel_SE_first_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_first_range, 0 );
+ vector float vf_pixel_SE_second_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_second_range, 0 );
+ vector float vf_pixel_SE_third_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_third_range, 0 );
+ vector float vf_pixel_SE_fourth_range = spu_convtf( (vector unsigned int) vuc_pixel_SE_fourth_range, 0 );
+
+ // first linear interpolation: EWtop
+ // EWtop = NW + EWweight*(NE-NW)
+ //
+ // first range
+ vector float vf_EWtop_first_range_tmp = spu_sub( vf_pixel_NE_first_range, vf_pixel_NW_first_range );
+ vector float vf_EWtop_first_range = spu_madd( vf_EWweight_first_range,
+ vf_EWtop_first_range_tmp,
+ vf_pixel_NW_first_range );
+
+ // second range
+ vector float vf_EWtop_second_range_tmp = spu_sub( vf_pixel_NE_second_range, vf_pixel_NW_second_range );
+ vector float vf_EWtop_second_range = spu_madd( vf_EWweight_second_range,
+ vf_EWtop_second_range_tmp,
+ vf_pixel_NW_second_range );
+
+ // third range
+ vector float vf_EWtop_third_range_tmp = spu_sub( vf_pixel_NE_third_range, vf_pixel_NW_third_range );
+ vector float vf_EWtop_third_range = spu_madd( vf_EWweight_third_range,
+ vf_EWtop_third_range_tmp,
+ vf_pixel_NW_third_range );
+
+ // fourth range
+ vector float vf_EWtop_fourth_range_tmp = spu_sub( vf_pixel_NE_fourth_range, vf_pixel_NW_fourth_range );
+ vector float vf_EWtop_fourth_range = spu_madd( vf_EWweight_fourth_range,
+ vf_EWtop_fourth_range_tmp,
+ vf_pixel_NW_fourth_range );
+
+
+
+ // second linear interpolation: EWbottom
+ // EWbottom = SW + EWweight*(SE-SW)
+ //
+ // first range
+ vector float vf_EWbottom_first_range_tmp = spu_sub( vf_pixel_SE_first_range, vf_pixel_SW_first_range );
+ vector float vf_EWbottom_first_range = spu_madd( vf_EWweight_first_range,
+ vf_EWbottom_first_range_tmp,
+ vf_pixel_SW_first_range );
+
+ // second range
+ vector float vf_EWbottom_second_range_tmp = spu_sub( vf_pixel_SE_second_range, vf_pixel_SW_second_range );
+ vector float vf_EWbottom_second_range = spu_madd( vf_EWweight_second_range,
+ vf_EWbottom_second_range_tmp,
+ vf_pixel_SW_second_range );
+ // first range
+ vector float vf_EWbottom_third_range_tmp = spu_sub( vf_pixel_SE_third_range, vf_pixel_SW_third_range );
+ vector float vf_EWbottom_third_range = spu_madd( vf_EWweight_third_range,
+ vf_EWbottom_third_range_tmp,
+ vf_pixel_SW_third_range );
+
+ // first range
+ vector float vf_EWbottom_fourth_range_tmp = spu_sub( vf_pixel_SE_fourth_range, vf_pixel_SW_fourth_range );
+ vector float vf_EWbottom_fourth_range = spu_madd( vf_EWweight_fourth_range,
+ vf_EWbottom_fourth_range_tmp,
+ vf_pixel_SW_fourth_range );
+
+
+
+ // third linear interpolation: the bilinear interpolated value
+ // result = EWtop + NSweight*(EWbottom-EWtop);
+ //
+ // first range
+ vector float vf_result_first_range_tmp = spu_sub( vf_EWbottom_first_range, vf_EWtop_first_range );
+ vector float vf_result_first_range = spu_madd( vf_NSweight,
+ vf_result_first_range_tmp,
+ vf_EWtop_first_range );
+
+ // second range
+ vector float vf_result_second_range_tmp = spu_sub( vf_EWbottom_second_range, vf_EWtop_second_range );
+ vector float vf_result_second_range = spu_madd( vf_NSweight,
+ vf_result_second_range_tmp,
+ vf_EWtop_second_range );
+
+ // third range
+ vector float vf_result_third_range_tmp = spu_sub( vf_EWbottom_third_range, vf_EWtop_third_range );
+ vector float vf_result_third_range = spu_madd( vf_NSweight,
+ vf_result_third_range_tmp,
+ vf_EWtop_third_range );
+
+ // fourth range
+ vector float vf_result_fourth_range_tmp = spu_sub( vf_EWbottom_fourth_range, vf_EWtop_fourth_range );
+ vector float vf_result_fourth_range = spu_madd( vf_NSweight,
+ vf_result_fourth_range_tmp,
+ vf_EWtop_fourth_range );
+
+
+
+ // convert back: using saturated arithmetic
+ vector unsigned int vui_result_first_range = vfloat_to_vuint( vf_result_first_range );
+ vector unsigned int vui_result_second_range = vfloat_to_vuint( vf_result_second_range );
+ vector unsigned int vui_result_third_range = vfloat_to_vuint( vf_result_third_range );
+ vector unsigned int vui_result_fourth_range = vfloat_to_vuint( vf_result_fourth_range );
+
+ // merge results->lower,upper
+ vector unsigned char vuc_mask_merge_result_first_second = { 0x03, 0x07, 0x0B, 0x0F,
+ 0x13, 0x17, 0x1B, 0x1F,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+
+ vector unsigned char vuc_mask_merge_result_third_fourth = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x07, 0x0B, 0x0F,
+ 0x13, 0x17, 0x1B, 0x1F };
+
+ vector unsigned char vuc_result_first_second =
+ spu_shuffle( (vector unsigned char) vui_result_first_range,
+ (vector unsigned char) vui_result_second_range,
+ vuc_mask_merge_result_first_second );
+
+ vector unsigned char vuc_result_third_fourth =
+ spu_shuffle( (vector unsigned char) vui_result_third_range,
+ (vector unsigned char) vui_result_fourth_range,
+ vuc_mask_merge_result_third_fourth );
+
+ // store result
+ *((vector unsigned char*)dst) = spu_or( vuc_result_first_second,
+ vuc_result_third_fourth );
+ dst += 16;
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/spulibs/fb_writer.c b/distrib/sdl-1.2.15/src/video/ps3/spulibs/fb_writer.c
new file mode 100644
index 0000000..0eb51cc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/spulibs/fb_writer.c
@@ -0,0 +1,193 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "spu_common.h"
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <stdio.h>
+#include <string.h>
+
+// Debugging
+//#define DEBUG
+
+#ifdef DEBUG
+#define deprintf(fmt, args... ) \
+ fprintf( stdout, fmt, ##args ); \
+ fflush( stdout );
+#else
+#define deprintf( fmt, args... )
+#endif
+
+void cpy_to_fb(unsigned int);
+
+/* fb_writer_spu parms */
+static volatile struct fb_writer_parms_t parms __attribute__ ((aligned(128)));
+
+/* Code running on SPU */
+int main(unsigned long long spe_id __attribute__ ((unused)), unsigned long long argp __attribute__ ((unused)))
+{
+ deprintf("[SPU] fb_writer_spu is up... (on SPE #%llu)\n", spe_id);
+ uint32_t ea_mfc, mbox;
+ // send ready message
+ spu_write_out_mbox(SPU_READY);
+
+ while (1) {
+ /* Check mailbox */
+ mbox = spu_read_in_mbox();
+ deprintf("[SPU] Message is %u\n", mbox);
+ switch (mbox) {
+ case SPU_EXIT:
+ deprintf("[SPU] fb_writer goes down...\n");
+ return 0;
+ case SPU_START:
+ break;
+ default:
+ deprintf("[SPU] Cannot handle message\n");
+ continue;
+ }
+
+ /* Tag Manager setup */
+ unsigned int tags;
+ tags = mfc_multi_tag_reserve(5);
+ if (tags == MFC_TAG_INVALID) {
+ deprintf("[SPU] Failed to reserve mfc tags on fb_writer\n");
+ return 0;
+ }
+
+ /* Framebuffer parms */
+ ea_mfc = spu_read_in_mbox();
+ deprintf("[SPU] Message on fb_writer is %u\n", ea_mfc);
+ spu_mfcdma32(&parms, (unsigned int)ea_mfc,
+ sizeof(struct fb_writer_parms_t), tags,
+ MFC_GET_CMD);
+ deprintf("[SPU] argp = %u\n", (unsigned int)argp);
+ DMA_WAIT_TAG(tags);
+
+ /* Copy parms->data to framebuffer */
+ deprintf("[SPU] Copying to framebuffer started\n");
+ cpy_to_fb(tags);
+ deprintf("[SPU] Copying to framebuffer done!\n");
+
+ mfc_multi_tag_release(tags, 5);
+ deprintf("[SPU] fb_writer_spu... done!\n");
+ /* Send FIN msg */
+ spu_write_out_mbox(SPU_FIN);
+ }
+
+ return 0;
+}
+
+void cpy_to_fb(unsigned int tag_id_base)
+{
+ unsigned int i;
+ unsigned char current_buf;
+ uint8_t *in = parms.data;
+
+ /* Align fb pointer which was centered before */
+ uint8_t *fb =
+ (unsigned char *)((unsigned int)parms.center & 0xFFFFFFF0);
+
+ uint32_t bounded_input_height = parms.bounded_input_height;
+ uint32_t bounded_input_width = parms.bounded_input_width;
+ uint32_t fb_pixel_size = parms.fb_pixel_size;
+
+ uint32_t out_line_stride = parms.out_line_stride;
+ uint32_t in_line_stride = parms.in_line_stride;
+ uint32_t in_line_size = bounded_input_width * fb_pixel_size;
+
+ current_buf = 0;
+
+ /* Local store buffer */
+ static volatile uint8_t buf[4][BUFFER_SIZE]
+ __attribute__ ((aligned(128)));
+ /* do 4-times multibuffering using DMA list, process in two steps */
+ for (i = 0; i < bounded_input_height >> 2; i++) {
+ /* first buffer */
+ DMA_WAIT_TAG(tag_id_base + 1);
+ // retrieve buffer
+ spu_mfcdma32(buf[0], (unsigned int)in, in_line_size,
+ tag_id_base + 1, MFC_GETB_CMD);
+ DMA_WAIT_TAG(tag_id_base + 1);
+ // store buffer
+ spu_mfcdma32(buf[0], (unsigned int)fb, in_line_size,
+ tag_id_base + 1, MFC_PUTB_CMD);
+ in += in_line_stride;
+ fb += out_line_stride;
+ deprintf("[SPU] 1st buffer copied in=0x%x, fb=0x%x\n", in,
+ fb);
+
+ /* second buffer */
+ DMA_WAIT_TAG(tag_id_base + 2);
+ // retrieve buffer
+ spu_mfcdma32(buf[1], (unsigned int)in, in_line_size,
+ tag_id_base + 2, MFC_GETB_CMD);
+ DMA_WAIT_TAG(tag_id_base + 2);
+ // store buffer
+ spu_mfcdma32(buf[1], (unsigned int)fb, in_line_size,
+ tag_id_base + 2, MFC_PUTB_CMD);
+ in += in_line_stride;
+ fb += out_line_stride;
+ deprintf("[SPU] 2nd buffer copied in=0x%x, fb=0x%x\n", in,
+ fb);
+
+ /* third buffer */
+ DMA_WAIT_TAG(tag_id_base + 3);
+ // retrieve buffer
+ spu_mfcdma32(buf[2], (unsigned int)in, in_line_size,
+ tag_id_base + 3, MFC_GETB_CMD);
+ DMA_WAIT_TAG(tag_id_base + 3);
+ // store buffer
+ spu_mfcdma32(buf[2], (unsigned int)fb, in_line_size,
+ tag_id_base + 3, MFC_PUTB_CMD);
+ in += in_line_stride;
+ fb += out_line_stride;
+ deprintf("[SPU] 3rd buffer copied in=0x%x, fb=0x%x\n", in,
+ fb);
+
+ /* fourth buffer */
+ DMA_WAIT_TAG(tag_id_base + 4);
+ // retrieve buffer
+ spu_mfcdma32(buf[3], (unsigned int)in, in_line_size,
+ tag_id_base + 4, MFC_GETB_CMD);
+ DMA_WAIT_TAG(tag_id_base + 4);
+ // store buffer
+ spu_mfcdma32(buf[3], (unsigned int)fb, in_line_size,
+ tag_id_base + 4, MFC_PUTB_CMD);
+ in += in_line_stride;
+ fb += out_line_stride;
+ deprintf("[SPU] 4th buffer copied in=0x%x, fb=0x%x\n", in,
+ fb);
+ deprintf("[SPU] Loop #%i, bounded_input_height=%i\n", i,
+ bounded_input_height >> 2);
+ }
+ DMA_WAIT_TAG(tag_id_base + 2);
+ DMA_WAIT_TAG(tag_id_base + 3);
+ DMA_WAIT_TAG(tag_id_base + 4);
+}
+
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/spulibs/spu_common.h b/distrib/sdl-1.2.15/src/video/ps3/spulibs/spu_common.h
new file mode 100644
index 0000000..42c328c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/spulibs/spu_common.h
@@ -0,0 +1,108 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+/* Common definitions/makros for SPUs */
+
+#ifndef _SPU_COMMON_H
+#define _SPU_COMMON_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+/* Tag management */
+#define DMA_WAIT_TAG(_tag) \
+ mfc_write_tag_mask(1<<(_tag)); \
+ mfc_read_tag_status_all();
+
+/* SPU mailbox messages */
+#define SPU_READY 0
+#define SPU_START 1
+#define SPU_FIN 2
+#define SPU_EXIT 3
+
+/* Tags */
+#define RETR_BUF 0
+#define STR_BUF 1
+#define TAG_INIT 2
+
+/* Buffersizes */
+#define MAX_HDTV_WIDTH 1920
+#define MAX_HDTV_HEIGHT 1080
+/* One stride of HDTV */
+#define BUFFER_SIZE 7680
+
+/* fb_writer ppu/spu exchange parms */
+struct fb_writer_parms_t {
+ uint8_t *data;
+ uint8_t *center;
+ uint32_t out_line_stride;
+ uint32_t in_line_stride;
+ uint32_t bounded_input_height;
+ uint32_t bounded_input_width;
+ uint32_t fb_pixel_size;
+
+ /* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
+ char padding[4];
+} __attribute__((aligned(128)));
+
+/* yuv2rgb ppu/spu exchange parms */
+struct yuv2rgb_parms_t {
+ uint8_t* y_plane;
+ uint8_t* v_plane;
+ uint8_t* u_plane;
+
+ uint8_t* dstBuffer;
+
+ unsigned int src_pixel_width;
+ unsigned int src_pixel_height;
+
+ /* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
+ char padding[128 - ((4 * sizeof(uint8_t *) + 2 * sizeof(unsigned int)) & 0x7F)];
+} __attribute__((aligned(128)));
+
+/* bilin_scaler ppu/spu exchange parms */
+struct scale_parms_t {
+ uint8_t* y_plane;
+ uint8_t* v_plane;
+ uint8_t* u_plane;
+
+ uint8_t* dstBuffer;
+
+ unsigned int src_pixel_width;
+ unsigned int src_pixel_height;
+
+ unsigned int dst_pixel_width;
+ unsigned int dst_pixel_height;
+
+ /* This padding is to fulfill the need for 16 byte alignment. On parm change, update! */
+ char padding[128 - ((4 * sizeof(uint8_t *) + 4 * sizeof(unsigned int)) & 0x7F)];
+} __attribute__((aligned(128)));
+
+#endif /* _SPU_COMMON_H */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/ps3/spulibs/yuv2rgb_converter.c b/distrib/sdl-1.2.15/src/video/ps3/spulibs/yuv2rgb_converter.c
new file mode 100644
index 0000000..5e16691
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/ps3/spulibs/yuv2rgb_converter.c
@@ -0,0 +1,629 @@
+/*
+ * SDL - Simple DirectMedia Layer
+ * CELL BE Support for PS3 Framebuffer
+ * Copyright (C) 2008, 2009 International Business Machines Corporation
+ *
+ * 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
+ *
+ * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
+ * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
+ * SPE code based on research by:
+ * Rene Becker
+ * Thimo Emmerich
+ */
+
+#include "spu_common.h"
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+// Debugging
+//#define DEBUG
+
+#ifdef DEBUG
+#define deprintf(fmt, args... ) \
+ fprintf( stdout, fmt, ##args ); \
+ fflush( stdout );
+#else
+#define deprintf( fmt, args... )
+#endif
+
+struct yuv2rgb_parms_t parms_converter __attribute__((aligned(128)));
+
+/* A maximum of 8 lines Y, therefore 4 lines V, 4 lines U are stored
+ * there might be the need to retrieve misaligned data, adjust
+ * incoming v and u plane to be able to handle this (add 128)
+ */
+unsigned char y_plane[2][(MAX_HDTV_WIDTH + 128) * 4] __attribute__((aligned(128)));
+unsigned char v_plane[2][(MAX_HDTV_WIDTH + 128) * 2] __attribute__((aligned(128)));
+unsigned char u_plane[2][(MAX_HDTV_WIDTH + 128) * 2] __attribute__((aligned(128)));
+
+/* A maximum of 4 lines BGRA are stored, 4 byte per pixel */
+unsigned char bgra[4 * MAX_HDTV_WIDTH * 4] __attribute__((aligned(128)));
+
+/* some vectors needed by the float to int conversion */
+static const vector float vec_255 = { 255.0f, 255.0f, 255.0f, 255.0f };
+static const vector float vec_0_1 = { 0.1f, 0.1f, 0.1f, 0.1f };
+
+void yuv_to_rgb_w16();
+void yuv_to_rgb_w32();
+
+void yuv_to_rgb_w16_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr, unsigned int width);
+void yuv_to_rgb_w32_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width);
+
+
+int main(unsigned long long spe_id __attribute__((unused)), unsigned long long argp __attribute__ ((unused)))
+{
+ deprintf("[SPU] yuv2rgb_spu is up... (on SPE #%llu)\n", spe_id);
+ uint32_t ea_mfc, mbox;
+ // send ready message
+ spu_write_out_mbox(SPU_READY);
+
+ while (1) {
+ /* Check mailbox */
+ mbox = spu_read_in_mbox();
+ deprintf("[SPU] Message is %u\n", mbox);
+ switch (mbox) {
+ case SPU_EXIT:
+ deprintf("[SPU] fb_writer goes down...\n");
+ return 0;
+ case SPU_START:
+ break;
+ default:
+ deprintf("[SPU] Cannot handle message\n");
+ continue;
+ }
+
+ /* Tag Manager setup */
+ unsigned int tag_id;
+ tag_id = mfc_multi_tag_reserve(1);
+ if (tag_id == MFC_TAG_INVALID) {
+ deprintf("[SPU] Failed to reserve mfc tags on yuv2rgb_converter\n");
+ return 0;
+ }
+
+ /* DMA transfer for the input parameters */
+ ea_mfc = spu_read_in_mbox();
+ deprintf("[SPU] Message on yuv2rgb_converter is %u\n", ea_mfc);
+ spu_mfcdma32(&parms_converter, (unsigned int)ea_mfc, sizeof(struct yuv2rgb_parms_t), tag_id, MFC_GET_CMD);
+ DMA_WAIT_TAG(tag_id);
+
+ /* There are alignment issues that involve handling of special cases
+ * a width of 32 results in a width of 16 in the chrominance
+ * --> choose the proper handling to optimize the performance
+ */
+ deprintf("[SPU] Convert %ix%i from YUV to RGB\n", parms_converter.src_pixel_width, parms_converter.src_pixel_height);
+ if (parms_converter.src_pixel_width & 0x1f) {
+ deprintf("[SPU] Using yuv_to_rgb_w16\n");
+ yuv_to_rgb_w16();
+ } else {
+ deprintf("[SPU] Using yuv_to_rgb_w32\n");
+ yuv_to_rgb_w32();
+ }
+
+ mfc_multi_tag_release(tag_id, 1);
+ deprintf("[SPU] yuv2rgb_spu... done!\n");
+ /* Send FIN message */
+ spu_write_out_mbox(SPU_FIN);
+ }
+
+ return 0;
+}
+
+
+/*
+ * float_to_char()
+ *
+ * converts a float to a character using saturated
+ * arithmetic
+ *
+ * @param s float for conversion
+ * @returns converted character
+ */
+inline static unsigned char float_to_char(float s) {
+ vector float vec_s = spu_splats(s);
+ vector unsigned int select_1 = spu_cmpgt(vec_0_1, vec_s);
+ vec_s = spu_sel(vec_s, vec_0_1, select_1);
+
+ vector unsigned int select_2 = spu_cmpgt(vec_s, vec_255);
+ vec_s = spu_sel(vec_s, vec_255, select_2);
+ return (unsigned char) spu_extract(vec_s,0);
+}
+
+
+/*
+ * vfloat_to_vuint()
+ *
+ * converts a float vector to an unsinged int vector using saturated
+ * arithmetic
+ *
+ * @param vec_s float vector for conversion
+ * @returns converted unsigned int vector
+ */
+inline static vector unsigned int vfloat_to_vuint(vector float vec_s) {
+ vector unsigned int select_1 = spu_cmpgt(vec_0_1, vec_s);
+ vec_s = spu_sel(vec_s, vec_0_1, select_1);
+
+ vector unsigned int select_2 = spu_cmpgt(vec_s, vec_255);
+ vec_s = spu_sel(vec_s, vec_255, select_2);
+ return spu_convtu(vec_s,0);
+}
+
+
+void yuv_to_rgb_w16() {
+ // Pixel dimensions of the picture
+ uint32_t width, height;
+
+ // Extract parameters
+ width = parms_converter.src_pixel_width;
+ height = parms_converter.src_pixel_height;
+
+ // Plane data management
+ // Y
+ unsigned char* ram_addr_y = parms_converter.y_plane;
+ // V
+ unsigned char* ram_addr_v = parms_converter.v_plane;
+ // U
+ unsigned char* ram_addr_u = parms_converter.u_plane;
+
+ // BGRA
+ unsigned char* ram_addr_bgra = parms_converter.dstBuffer;
+
+ // Strides
+ unsigned int stride_y = width;
+ unsigned int stride_vu = width>>1;
+
+ // Buffer management
+ unsigned int buf_idx = 0;
+ unsigned int size_4lines_y = stride_y<<2;
+ unsigned int size_2lines_y = stride_y<<1;
+ unsigned int size_2lines_vu = stride_vu<<1;
+
+ // 2*width*4byte_per_pixel
+ unsigned int size_2lines_bgra = width<<3;
+
+
+ // start double-buffered processing
+ // 4 lines y
+ spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y, size_4lines_y, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ // 2 lines v
+ spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ // 2 lines u
+ spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ // Wait for these transfers to be completed
+ DMA_WAIT_TAG((RETR_BUF + buf_idx));
+
+ unsigned int i;
+ for(i=0; i<(height>>2)-1; i++) {
+
+ buf_idx^=1;
+
+ // 4 lines y
+ spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y+size_4lines_y, size_4lines_y, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ // 2 lines v
+ spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v+size_2lines_vu, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ // 2 lines u
+ spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u+size_2lines_vu, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD);
+
+ DMA_WAIT_TAG((RETR_BUF + buf_idx));
+
+ buf_idx^=1;
+
+
+ // Convert YUV to BGRA, store it back (first two lines)
+ yuv_to_rgb_w16_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width);
+
+ // Next two lines
+ yuv_to_rgb_w16_line(y_plane[buf_idx] + size_2lines_y,
+ v_plane[buf_idx] + stride_vu,
+ u_plane[buf_idx] + stride_vu,
+ bgra + size_2lines_bgra,
+ width);
+
+ // Wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+
+ // Store converted lines in two steps->max transfer size 16384
+ spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+ spu_mfcdma32(bgra+size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+
+ // Move 4 lines
+ ram_addr_y += size_4lines_y;
+ ram_addr_v += size_2lines_vu;
+ ram_addr_u += size_2lines_vu;
+
+ buf_idx^=1;
+ }
+
+ // Convert YUV to BGRA, store it back (first two lines)
+ yuv_to_rgb_w16_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width);
+
+ // Next two lines
+ yuv_to_rgb_w16_line(y_plane[buf_idx] + size_2lines_y,
+ v_plane[buf_idx] + stride_vu,
+ u_plane[buf_idx] + stride_vu,
+ bgra + size_2lines_bgra,
+ width);
+
+ // Wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+ spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+ spu_mfcdma32(bgra+size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+
+ // wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+
+}
+
+
+void yuv_to_rgb_w32() {
+ // Pixel dimensions of the picture
+ uint32_t width, height;
+
+ // Extract parameters
+ width = parms_converter.src_pixel_width;
+ height = parms_converter.src_pixel_height;
+
+ // Plane data management
+ // Y
+ unsigned char* ram_addr_y = parms_converter.y_plane;
+ // V
+ unsigned char* ram_addr_v = parms_converter.v_plane;
+ // U
+ unsigned char* ram_addr_u = parms_converter.u_plane;
+
+ // BGRA
+ unsigned char* ram_addr_bgra = parms_converter.dstBuffer;
+
+ // Strides
+ unsigned int stride_y = width;
+ unsigned int stride_vu = width>>1;
+
+ // Buffer management
+ unsigned int buf_idx = 0;
+ unsigned int size_4lines_y = stride_y<<2;
+ unsigned int size_2lines_y = stride_y<<1;
+ unsigned int size_2lines_vu = stride_vu<<1;
+
+ // 2*width*4byte_per_pixel
+ unsigned int size_2lines_bgra = width<<3;
+
+ // start double-buffered processing
+ // 4 lines y
+ spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y, size_4lines_y, RETR_BUF + buf_idx, MFC_GET_CMD);
+ // 2 lines v
+ spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD);
+ // 2 lines u
+ spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD);
+
+ // Wait for these transfers to be completed
+ DMA_WAIT_TAG((RETR_BUF + buf_idx));
+
+ unsigned int i;
+ for(i=0; i < (height>>2)-1; i++) {
+ buf_idx^=1;
+ // 4 lines y
+ spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y+size_4lines_y, size_4lines_y, RETR_BUF + buf_idx, MFC_GET_CMD);
+ deprintf("4lines = %d\n", size_4lines_y);
+ // 2 lines v
+ spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v+size_2lines_vu, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD);
+ deprintf("2lines = %d\n", size_2lines_vu);
+ // 2 lines u
+ spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u+size_2lines_vu, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD);
+ deprintf("2lines = %d\n", size_2lines_vu);
+
+ DMA_WAIT_TAG((RETR_BUF + buf_idx));
+
+ buf_idx^=1;
+
+ // Convert YUV to BGRA, store it back (first two lines)
+ yuv_to_rgb_w32_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width);
+
+ // Next two lines
+ yuv_to_rgb_w32_line(y_plane[buf_idx] + size_2lines_y,
+ v_plane[buf_idx] + stride_vu,
+ u_plane[buf_idx] + stride_vu,
+ bgra + size_2lines_bgra,
+ width);
+
+ // Wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+
+ // Store converted lines in two steps->max transfer size 16384
+ spu_mfcdma32(bgra, (unsigned int)ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+ spu_mfcdma32(bgra + size_2lines_bgra, (unsigned int)ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+
+ // Move 4 lines
+ ram_addr_y += size_4lines_y;
+ ram_addr_v += size_2lines_vu;
+ ram_addr_u += size_2lines_vu;
+
+ buf_idx^=1;
+ }
+
+ // Convert YUV to BGRA, store it back (first two lines)
+ yuv_to_rgb_w32_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width);
+
+ // Next two lines
+ yuv_to_rgb_w32_line(y_plane[buf_idx] + size_2lines_y,
+ v_plane[buf_idx] + stride_vu,
+ u_plane[buf_idx] + stride_vu,
+ bgra + size_2lines_bgra,
+ width);
+
+ // Wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+ spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+ ram_addr_bgra += size_2lines_bgra;
+ spu_mfcdma32(bgra + size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD);
+
+ // Wait for previous storing transfer to be completed
+ DMA_WAIT_TAG(STR_BUF);
+}
+
+
+/* Some vectors needed by the yuv 2 rgb conversion algorithm */
+const vector float vec_minus_128 = { -128.0f, -128.0f, -128.0f, -128.0f };
+const vector unsigned char vec_null = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+const vector unsigned char vec_char2int_first = { 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13 };
+const vector unsigned char vec_char2int_second = { 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17 };
+const vector unsigned char vec_char2int_third = { 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1B };
+const vector unsigned char vec_char2int_fourth = { 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1F };
+
+const vector float vec_R_precalc_coeff = {1.403f, 1.403f, 1.403f, 1.403f};
+const vector float vec_Gu_precalc_coeff = {-0.344f, -0.344f, -0.344f, -0.344f};
+const vector float vec_Gv_precalc_coeff = {-0.714f, -0.714f, -0.714f, -0.714f};
+const vector float vec_B_precalc_coeff = {1.773f, 1.773f, 1.773f, 1.773f};
+
+const vector unsigned int vec_alpha = { 255 << 24, 255 << 24, 255 << 24, 255 << 24 };
+
+const vector unsigned char vec_select_floats_upper = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07 };
+const vector unsigned char vec_select_floats_lower = { 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0C, 0x0D, 0x0E, 0x0F };
+
+
+/*
+ * yuv_to_rgb_w16()
+ *
+ * processes to line of yuv-input, width has to be a multiple of 16
+ * two lines of yuv are taken as input
+ *
+ * @param y_addr address of the y plane in local store
+ * @param v_addr address of the v plane in local store
+ * @param u_addr address of the u plane in local store
+ * @param bgra_addr_ address of the bgra output buffer
+ * @param width the width in pixel
+ */
+void yuv_to_rgb_w16_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width) {
+ // each pixel is stored as an integer
+ unsigned int* bgra_addr = (unsigned int*) bgra_addr_;
+
+ unsigned int x;
+ for(x = 0; x < width; x+=2) {
+ // Gehe zweischrittig durch die zeile, da jeder u und v wert fuer 4 pixel(zwei hoch, zwei breit) gilt
+ const unsigned char Y_1 = *(y_addr + x);
+ const unsigned char Y_2 = *(y_addr + x + 1);
+ const unsigned char Y_3 = *(y_addr + x + width);
+ const unsigned char Y_4 = *(y_addr + x + width + 1);
+ const unsigned char U = *(u_addr + (x >> 1));
+ const unsigned char V = *(v_addr + (x >> 1));
+
+ float V_minus_128 = (float)((float)V - 128.0f);
+ float U_minus_128 = (float)((float)U - 128.0f);
+
+ float R_precalculate = 1.403f * V_minus_128;
+ float G_precalculate = -(0.344f * U_minus_128 + 0.714f * V_minus_128);
+ float B_precalculate = 1.773f * U_minus_128;
+
+ const unsigned char R_1 = float_to_char((Y_1 + R_precalculate));
+ const unsigned char R_2 = float_to_char((Y_2 + R_precalculate));
+ const unsigned char R_3 = float_to_char((Y_3 + R_precalculate));
+ const unsigned char R_4 = float_to_char((Y_4 + R_precalculate));
+ const unsigned char G_1 = float_to_char((Y_1 + G_precalculate));
+ const unsigned char G_2 = float_to_char((Y_2 + G_precalculate));
+ const unsigned char G_3 = float_to_char((Y_3 + G_precalculate));
+ const unsigned char G_4 = float_to_char((Y_4 + G_precalculate));
+ const unsigned char B_1 = float_to_char((Y_1 + B_precalculate));
+ const unsigned char B_2 = float_to_char((Y_2 + B_precalculate));
+ const unsigned char B_3 = float_to_char((Y_3 + B_precalculate));
+ const unsigned char B_4 = float_to_char((Y_4 + B_precalculate));
+
+ *(bgra_addr + x) = (B_1 << 0)| (G_1 << 8) | (R_1 << 16) | (255 << 24);
+ *(bgra_addr + x + 1) = (B_2 << 0)| (G_2 << 8) | (R_2 << 16) | (255 << 24);
+ *(bgra_addr + x + width) = (B_3 << 0)| (G_3 << 8) | (R_3 << 16) | (255 << 24);
+ *(bgra_addr + x + width + 1) = (B_4 << 0)| (G_4 << 8) | (R_4 << 16) | (255 << 24);
+ }
+}
+
+
+/*
+ * yuv_to_rgb_w32()
+ *
+ * processes to line of yuv-input, width has to be a multiple of 32
+ * two lines of yuv are taken as input
+ *
+ * @param y_addr address of the y plane in local store
+ * @param v_addr address of the v plane in local store
+ * @param u_addr address of the u plane in local store
+ * @param bgra_addr_ address of the bgra output buffer
+ * @param width the width in pixel
+ */
+void yuv_to_rgb_w32_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width) {
+ // each pixel is stored as an integer
+ unsigned int* bgra_addr = (unsigned int*) bgra_addr_;
+
+ unsigned int x;
+ for(x = 0; x < width; x+=32) {
+ // Gehe zweischrittig durch die zeile, da jeder u und v wert fuer 4 pixel(zwei hoch, zwei breit) gilt
+
+ const vector unsigned char vchar_Y_1 = *((vector unsigned char*)(y_addr + x));
+ const vector unsigned char vchar_Y_2 = *((vector unsigned char*)(y_addr + x + 16));
+ const vector unsigned char vchar_Y_3 = *((vector unsigned char*)(y_addr + x + width));
+ const vector unsigned char vchar_Y_4 = *((vector unsigned char*)(y_addr + x + width + 16));
+ const vector unsigned char vchar_U = *((vector unsigned char*)(u_addr + (x >> 1)));
+ const vector unsigned char vchar_V = *((vector unsigned char*)(v_addr + (x >> 1)));
+
+ const vector float vfloat_U_1 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_first), 0),vec_minus_128);
+ const vector float vfloat_U_2 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_second), 0),vec_minus_128);
+ const vector float vfloat_U_3 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_third), 0),vec_minus_128);
+ const vector float vfloat_U_4 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_fourth), 0),vec_minus_128);
+
+ const vector float vfloat_V_1 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_first), 0),vec_minus_128);
+ const vector float vfloat_V_2 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_second), 0),vec_minus_128);
+ const vector float vfloat_V_3 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_third), 0),vec_minus_128);
+ const vector float vfloat_V_4 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_fourth), 0),vec_minus_128);
+
+ vector float Y_1 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_first), 0);
+ vector float Y_2 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_second), 0);
+ vector float Y_3 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_third), 0);
+ vector float Y_4 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_fourth), 0);
+ vector float Y_5 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_first), 0);
+ vector float Y_6 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_second), 0);
+ vector float Y_7 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_third), 0);
+ vector float Y_8 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_fourth), 0);
+ vector float Y_9 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_first), 0);
+ vector float Y_10 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_second), 0);
+ vector float Y_11 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_third), 0);
+ vector float Y_12 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_fourth), 0);
+ vector float Y_13 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_first), 0);
+ vector float Y_14 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_second), 0);
+ vector float Y_15 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_third), 0);
+ vector float Y_16 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_fourth), 0);
+
+ const vector float R1a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_1);
+ const vector float R2a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_2);
+ const vector float R3a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_3);
+ const vector float R4a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_4);
+
+ const vector float R1_precalculate = spu_shuffle(R1a_precalculate, R1a_precalculate, vec_select_floats_upper);
+ const vector float R2_precalculate = spu_shuffle(R1a_precalculate, R1a_precalculate, vec_select_floats_lower);
+ const vector float R3_precalculate = spu_shuffle(R2a_precalculate, R2a_precalculate, vec_select_floats_upper);
+ const vector float R4_precalculate = spu_shuffle(R2a_precalculate, R2a_precalculate, vec_select_floats_lower);
+ const vector float R5_precalculate = spu_shuffle(R3a_precalculate, R3a_precalculate, vec_select_floats_upper);
+ const vector float R6_precalculate = spu_shuffle(R3a_precalculate, R3a_precalculate, vec_select_floats_lower);
+ const vector float R7_precalculate = spu_shuffle(R4a_precalculate, R4a_precalculate, vec_select_floats_upper);
+ const vector float R8_precalculate = spu_shuffle(R4a_precalculate, R4a_precalculate, vec_select_floats_lower);
+
+
+ const vector float G1a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_1, spu_mul(vfloat_V_1, vec_Gv_precalc_coeff));
+ const vector float G2a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_2, spu_mul(vfloat_V_2, vec_Gv_precalc_coeff));
+ const vector float G3a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_3, spu_mul(vfloat_V_3, vec_Gv_precalc_coeff));
+ const vector float G4a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_4, spu_mul(vfloat_V_4, vec_Gv_precalc_coeff));
+
+ const vector float G1_precalculate = spu_shuffle(G1a_precalculate, G1a_precalculate, vec_select_floats_upper);
+ const vector float G2_precalculate = spu_shuffle(G1a_precalculate, G1a_precalculate, vec_select_floats_lower);
+ const vector float G3_precalculate = spu_shuffle(G2a_precalculate, G2a_precalculate, vec_select_floats_upper);
+ const vector float G4_precalculate = spu_shuffle(G2a_precalculate, G2a_precalculate, vec_select_floats_lower);
+ const vector float G5_precalculate = spu_shuffle(G3a_precalculate, G3a_precalculate, vec_select_floats_upper);
+ const vector float G6_precalculate = spu_shuffle(G3a_precalculate, G3a_precalculate, vec_select_floats_lower);
+ const vector float G7_precalculate = spu_shuffle(G4a_precalculate, G4a_precalculate, vec_select_floats_upper);
+ const vector float G8_precalculate = spu_shuffle(G4a_precalculate, G4a_precalculate, vec_select_floats_lower);
+
+
+ const vector float B1a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_1);
+ const vector float B2a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_2);
+ const vector float B3a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_3);
+ const vector float B4a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_4);
+
+ const vector float B1_precalculate = spu_shuffle(B1a_precalculate, B1a_precalculate, vec_select_floats_upper);
+ const vector float B2_precalculate = spu_shuffle(B1a_precalculate, B1a_precalculate, vec_select_floats_lower);
+ const vector float B3_precalculate = spu_shuffle(B2a_precalculate, B2a_precalculate, vec_select_floats_upper);
+ const vector float B4_precalculate = spu_shuffle(B2a_precalculate, B2a_precalculate, vec_select_floats_lower);
+ const vector float B5_precalculate = spu_shuffle(B3a_precalculate, B3a_precalculate, vec_select_floats_upper);
+ const vector float B6_precalculate = spu_shuffle(B3a_precalculate, B3a_precalculate, vec_select_floats_lower);
+ const vector float B7_precalculate = spu_shuffle(B4a_precalculate, B4a_precalculate, vec_select_floats_upper);
+ const vector float B8_precalculate = spu_shuffle(B4a_precalculate, B4a_precalculate, vec_select_floats_lower);
+
+
+ const vector unsigned int R_1 = vfloat_to_vuint(spu_add( Y_1, R1_precalculate));
+ const vector unsigned int R_2 = vfloat_to_vuint(spu_add( Y_2, R2_precalculate));
+ const vector unsigned int R_3 = vfloat_to_vuint(spu_add( Y_3, R3_precalculate));
+ const vector unsigned int R_4 = vfloat_to_vuint(spu_add( Y_4, R4_precalculate));
+ const vector unsigned int R_5 = vfloat_to_vuint(spu_add( Y_5, R5_precalculate));
+ const vector unsigned int R_6 = vfloat_to_vuint(spu_add( Y_6, R6_precalculate));
+ const vector unsigned int R_7 = vfloat_to_vuint(spu_add( Y_7, R7_precalculate));
+ const vector unsigned int R_8 = vfloat_to_vuint(spu_add( Y_8, R8_precalculate));
+ const vector unsigned int R_9 = vfloat_to_vuint(spu_add( Y_9, R1_precalculate));
+ const vector unsigned int R_10 = vfloat_to_vuint(spu_add(Y_10, R2_precalculate));
+ const vector unsigned int R_11 = vfloat_to_vuint(spu_add(Y_11, R3_precalculate));
+ const vector unsigned int R_12 = vfloat_to_vuint(spu_add(Y_12, R4_precalculate));
+ const vector unsigned int R_13 = vfloat_to_vuint(spu_add(Y_13, R5_precalculate));
+ const vector unsigned int R_14 = vfloat_to_vuint(spu_add(Y_14, R6_precalculate));
+ const vector unsigned int R_15 = vfloat_to_vuint(spu_add(Y_15, R7_precalculate));
+ const vector unsigned int R_16 = vfloat_to_vuint(spu_add(Y_16, R8_precalculate));
+
+ const vector unsigned int G_1 = vfloat_to_vuint(spu_add( Y_1, G1_precalculate));
+ const vector unsigned int G_2 = vfloat_to_vuint(spu_add( Y_2, G2_precalculate));
+ const vector unsigned int G_3 = vfloat_to_vuint(spu_add( Y_3, G3_precalculate));
+ const vector unsigned int G_4 = vfloat_to_vuint(spu_add( Y_4, G4_precalculate));
+ const vector unsigned int G_5 = vfloat_to_vuint(spu_add( Y_5, G5_precalculate));
+ const vector unsigned int G_6 = vfloat_to_vuint(spu_add( Y_6, G6_precalculate));
+ const vector unsigned int G_7 = vfloat_to_vuint(spu_add( Y_7, G7_precalculate));
+ const vector unsigned int G_8 = vfloat_to_vuint(spu_add( Y_8, G8_precalculate));
+ const vector unsigned int G_9 = vfloat_to_vuint(spu_add( Y_9, G1_precalculate));
+ const vector unsigned int G_10 = vfloat_to_vuint(spu_add(Y_10, G2_precalculate));
+ const vector unsigned int G_11 = vfloat_to_vuint(spu_add(Y_11, G3_precalculate));
+ const vector unsigned int G_12 = vfloat_to_vuint(spu_add(Y_12, G4_precalculate));
+ const vector unsigned int G_13 = vfloat_to_vuint(spu_add(Y_13, G5_precalculate));
+ const vector unsigned int G_14 = vfloat_to_vuint(spu_add(Y_14, G6_precalculate));
+ const vector unsigned int G_15 = vfloat_to_vuint(spu_add(Y_15, G7_precalculate));
+ const vector unsigned int G_16 = vfloat_to_vuint(spu_add(Y_16, G8_precalculate));
+
+ const vector unsigned int B_1 = vfloat_to_vuint(spu_add( Y_1, B1_precalculate));
+ const vector unsigned int B_2 = vfloat_to_vuint(spu_add( Y_2, B2_precalculate));
+ const vector unsigned int B_3 = vfloat_to_vuint(spu_add( Y_3, B3_precalculate));
+ const vector unsigned int B_4 = vfloat_to_vuint(spu_add( Y_4, B4_precalculate));
+ const vector unsigned int B_5 = vfloat_to_vuint(spu_add( Y_5, B5_precalculate));
+ const vector unsigned int B_6 = vfloat_to_vuint(spu_add( Y_6, B6_precalculate));
+ const vector unsigned int B_7 = vfloat_to_vuint(spu_add( Y_7, B7_precalculate));
+ const vector unsigned int B_8 = vfloat_to_vuint(spu_add( Y_8, B8_precalculate));
+ const vector unsigned int B_9 = vfloat_to_vuint(spu_add( Y_9, B1_precalculate));
+ const vector unsigned int B_10 = vfloat_to_vuint(spu_add(Y_10, B2_precalculate));
+ const vector unsigned int B_11 = vfloat_to_vuint(spu_add(Y_11, B3_precalculate));
+ const vector unsigned int B_12 = vfloat_to_vuint(spu_add(Y_12, B4_precalculate));
+ const vector unsigned int B_13 = vfloat_to_vuint(spu_add(Y_13, B5_precalculate));
+ const vector unsigned int B_14 = vfloat_to_vuint(spu_add(Y_14, B6_precalculate));
+ const vector unsigned int B_15 = vfloat_to_vuint(spu_add(Y_15, B7_precalculate));
+ const vector unsigned int B_16 = vfloat_to_vuint(spu_add(Y_16, B8_precalculate));
+
+ *((vector unsigned int*)(bgra_addr + x)) = spu_or(spu_or(vec_alpha, B_1), spu_or(spu_slqwbyte( R_1, 2),spu_slqwbyte(G_1, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 4)) = spu_or(spu_or(vec_alpha, B_2), spu_or(spu_slqwbyte( R_2, 2),spu_slqwbyte(G_2, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 8)) = spu_or(spu_or(vec_alpha, B_3), spu_or(spu_slqwbyte( R_3, 2),spu_slqwbyte(G_3, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 12)) = spu_or(spu_or(vec_alpha, B_4), spu_or(spu_slqwbyte( R_4, 2),spu_slqwbyte(G_4, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 16)) = spu_or(spu_or(vec_alpha, B_5), spu_or(spu_slqwbyte( R_5, 2),spu_slqwbyte(G_5, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 20)) = spu_or(spu_or(vec_alpha, B_6), spu_or(spu_slqwbyte( R_6, 2),spu_slqwbyte(G_6, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 24)) = spu_or(spu_or(vec_alpha, B_7), spu_or(spu_slqwbyte( R_7, 2),spu_slqwbyte(G_7, 1)));
+ *((vector unsigned int*)(bgra_addr + x + 28)) = spu_or(spu_or(vec_alpha, B_8), spu_or(spu_slqwbyte( R_8, 2),spu_slqwbyte(G_8, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width)) = spu_or(spu_or(vec_alpha, B_9), spu_or(spu_slqwbyte( R_9, 2),spu_slqwbyte(G_9, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 4)) = spu_or(spu_or(vec_alpha, B_10), spu_or(spu_slqwbyte(R_10, 2),spu_slqwbyte(G_10, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 8)) = spu_or(spu_or(vec_alpha, B_11), spu_or(spu_slqwbyte(R_11, 2),spu_slqwbyte(G_11, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 12)) = spu_or(spu_or(vec_alpha, B_12), spu_or(spu_slqwbyte(R_12, 2),spu_slqwbyte(G_12, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 16)) = spu_or(spu_or(vec_alpha, B_13), spu_or(spu_slqwbyte(R_13, 2),spu_slqwbyte(G_13, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 20)) = spu_or(spu_or(vec_alpha, B_14), spu_or(spu_slqwbyte(R_14, 2),spu_slqwbyte(G_14, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 24)) = spu_or(spu_or(vec_alpha, B_15), spu_or(spu_slqwbyte(R_15, 2),spu_slqwbyte(G_15, 1)));
+ *((vector unsigned int*)(bgra_addr + x + width + 28)) = spu_or(spu_or(vec_alpha, B_16), spu_or(spu_slqwbyte(R_16, 2),spu_slqwbyte(G_16, 1)));
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.cc
new file mode 100644
index 0000000..8daf1c5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.cc
@@ -0,0 +1,63 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <qpe/qpeapplication.h>
+#include <qapplication.h>
+#include <qevent.h>
+
+#include "SDL_thread.h"
+#include "SDL_timer.h"
+#include "SDL_error.h"
+
+/* Flag to tell whether or not the Be application is active or not */
+int SDL_QPEAppActive = 0;
+static QPEApplication *app;
+
+int SDL_InitQPEApp() {
+ if(SDL_QPEAppActive <= 0) {
+ if(!qApp) {
+ int argc = 1;
+ char *argv[] = { { "SDLApp" } };
+ app = new QPEApplication(argc, argv);
+ QWidget dummy;
+ app->showMainWidget(&dummy);
+ } else {
+ app = (QPEApplication*)qApp;
+ }
+ SDL_QPEAppActive++;
+ }
+ return 0;
+}
+
+/* Quit the QPE Application, if there's nothing left to do */
+void SDL_QuitQPEApp(void)
+{
+ /* Decrement the application reference count */
+ SDL_QPEAppActive--;
+ /* If the reference count reached zero, clean up the app */
+ if ( SDL_QPEAppActive == 0 && app) {
+ delete app;
+ app = 0;
+ qApp = 0;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.h
new file mode 100644
index 0000000..8a9ab77
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QPEApp.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the QPE application loop */
+
+/* Initialize the QPE Application, if it's not already started */
+extern int SDL_InitQPEApp(void);
+
+/* Quit the QPE Application, if there's nothing left to do */
+extern void SDL_QuitQPEApp(void);
+
+/* Flag to tell whether the app is active or not */
+extern int SDL_QPEAppActive;
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.cc
new file mode 100644
index 0000000..04474ed
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.cc
@@ -0,0 +1,527 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QWin.h"
+#include <qapplication.h>
+#include <qdirectpainter_qws.h>
+
+screenRotationT screenRotation = SDL_QT_NO_ROTATION;
+
+SDL_QWin::SDL_QWin(const QSize& size)
+ : QWidget(0, "SDL_main"), my_painter(0), my_image(0),
+ my_inhibit_resize(false), my_mouse_pos(-1,-1), my_flags(0),
+ my_has_fullscreen(false), my_locked(0)
+{
+ setBackgroundMode(NoBackground);
+}
+
+SDL_QWin::~SDL_QWin() {
+ // Nothing to do yet.
+ if(my_image) {
+ delete my_image;
+ }
+}
+
+void SDL_QWin::setImage(QImage *image) {
+ if ( my_image ) {
+ delete my_image;
+ }
+ my_image = image;
+ // setFixedSize(image->size());
+}
+
+void SDL_QWin::resizeEvent(QResizeEvent *e) {
+ if(size() != qApp->desktop()->size()) {
+ // Widget is not the correct size, so do the fullscreen magic
+ my_has_fullscreen = false;
+ enableFullscreen();
+ }
+ if(my_inhibit_resize) {
+ my_inhibit_resize = false;
+ } else {
+ SDL_PrivateResize(e->size().width(), e->size().height());
+ }
+}
+
+void SDL_QWin::focusInEvent(QFocusEvent *) {
+ // Always do it here, no matter the size.
+ enableFullscreen();
+ SDL_PrivateAppActive(true, SDL_APPINPUTFOCUS);
+}
+
+void SDL_QWin::focusOutEvent(QFocusEvent *) {
+ my_has_fullscreen = false;
+ SDL_PrivateAppActive(false, SDL_APPINPUTFOCUS);
+}
+
+void SDL_QWin::closeEvent(QCloseEvent *e) {
+ SDL_PrivateQuit();
+ e->ignore();
+}
+
+void SDL_QWin::setMousePos(const QPoint &pos) {
+ if(my_image->width() == height()) {
+ if (screenRotation == SDL_QT_ROTATION_90)
+ my_mouse_pos = QPoint(height()-pos.y(), pos.x());
+ else if (screenRotation == SDL_QT_ROTATION_270)
+ my_mouse_pos = QPoint(pos.y(), width()-pos.x());
+ } else {
+ my_mouse_pos = pos;
+ }
+}
+
+void SDL_QWin::mouseMoveEvent(QMouseEvent *e) {
+ Qt::ButtonState button = e->button();
+ int sdlstate = 0;
+ if( (button & Qt::LeftButton)) {
+ sdlstate |= SDL_BUTTON_LMASK;
+ }
+ if( (button & Qt::RightButton)) {
+ sdlstate |= SDL_BUTTON_RMASK;
+ }
+ if( (button & Qt::MidButton)) {
+ sdlstate |= SDL_BUTTON_MMASK;
+ }
+ setMousePos(e->pos());
+ SDL_PrivateMouseMotion(sdlstate, 0, my_mouse_pos.x(), my_mouse_pos.y());
+}
+
+void SDL_QWin::mousePressEvent(QMouseEvent *e) {
+ mouseMoveEvent(e);
+ Qt::ButtonState button = e->button();
+ SDL_PrivateMouseButton(SDL_PRESSED,
+ (button & Qt::LeftButton) ? 1 :
+ ((button & Qt::RightButton) ? 2 : 3),
+ my_mouse_pos.x(), my_mouse_pos.y());
+}
+
+void SDL_QWin::mouseReleaseEvent(QMouseEvent *e) {
+ setMousePos(e->pos());
+ Qt::ButtonState button = e->button();
+ SDL_PrivateMouseButton(SDL_RELEASED,
+ (button & Qt::LeftButton) ? 1 :
+ ((button & Qt::RightButton) ? 2 : 3),
+ my_mouse_pos.x(), my_mouse_pos.y());
+ my_mouse_pos = QPoint(-1, -1);
+}
+
+static inline void
+gs_fastRotateBlit_3 ( unsigned short *fb,
+ unsigned short *bits,
+ const QRect& rect )
+{
+ // FIXME: this only works correctly for 240x320 displays
+ int startx, starty;
+ int width, height;
+
+ startx = rect.left() >> 1;
+ starty = rect.top() >> 1;
+ width = ((rect.right() - rect.left()) >> 1) + 2;
+ height = ((rect.bottom() - rect.top()) >> 1) + 2;
+
+ if((startx+width) > 120) {
+ width = 120 - startx; // avoid horizontal overflow
+ }
+ if((starty+height) > 160) {
+ height = 160 - starty; // avoid vertical overflow
+ }
+
+ ulong *sp1, *sp2, *dp1, *dp2;
+ ulong stop, sbot, dtop, dbot;
+
+ sp1 = (ulong*)bits + startx + starty*240;
+ sp2 = sp1 + 120;
+ dp1 = (ulong *)fb + (159 - starty) + startx*320;
+ dp2 = dp1 + 160;
+ int rowadd = (-320*width) - 1;
+ int rowadd2 = 240 - width;
+ // transfer in cells of 2x2 pixels in words
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ // read source pixels
+ stop = *sp1;
+ sbot = *sp2;
+ // rotate pixels
+ dtop = (sbot & 0xffff) + ((stop & 0xffff)<<16);
+ dbot = ((sbot & 0xffff0000)>>16) + (stop & 0xffff0000);
+ // write to framebuffer
+ *dp1 = dtop;
+ *dp2 = dbot;
+ // update source ptrs
+ sp1++; sp2++;
+ // update dest ptrs - 2 pix at a time
+ dp1 += 320;
+ dp2 += 320;
+ }
+ // adjust src ptrs - skip a row as we work in pairs
+ sp1 += rowadd2;
+ sp2 += rowadd2;
+ // adjust dest ptrs for rotation
+ dp1 += rowadd;
+ dp2 += rowadd;
+ }
+}
+
+static inline void
+gs_fastRotateBlit_1 ( unsigned short *fb,
+ unsigned short *bits,
+ const QRect& rect ) {
+ // FIXME: this only works correctly for 240x320 displays
+ int startx, starty;
+ int width, height;
+
+ startx = rect.left() >> 1;
+ starty = rect.top() >> 1;
+ width = ((rect.right() - rect.left()) >> 1) + 2;
+ height = ((rect.bottom() - rect.top()) >> 1) + 2;
+
+ if((startx+width) > 120) {
+ width = 120 - startx; // avoid horizontal overflow
+ }
+ if((starty+height) > 160) {
+ height = 160 - starty; // avoid vertical overflow
+ }
+
+ ulong *sp1, *sp2, *dp1, *dp2;
+ ulong stop, sbot, dtop, dbot;
+ fb += 320*239; // Move "fb" to top left corner
+ sp1 = (ulong*)bits + startx + starty*240;
+ sp2 = sp1 + 120;
+ dp1 = (ulong*)fb - startx * 320 - starty;
+ dp2 = dp1 - 160;
+ int rowadd = (320*width) + 1;
+ int rowadd2 = 240 - width;
+ // transfer in cells of 2x2 pixels in words
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ // read
+ stop = *sp1;
+ sbot = *sp2;
+ // rotate
+ dtop = (stop & 0xffff) + ((sbot & 0xffff)<<16);
+ dbot = ((stop & 0xffff0000)>>16) + (sbot & 0xffff0000);
+ // write
+ *dp1 = dtop;
+ *dp2 = dbot;
+ // update source ptrs
+ sp1++; sp2++;
+ // update dest ptrs - 2 pix at a time
+ dp1 -= 320;
+ dp2 -= 320;
+ }
+ // adjust src ptrs - skip a row as we work in pairs
+ sp1 += rowadd2;
+ sp2 += rowadd2;
+ // adjust dest ptrs for rotation
+ dp1 += rowadd;
+ dp2 += rowadd;
+ }
+}
+
+// desktop, SL-A300 etc
+bool SDL_QWin::repaintRotation0(const QRect& rect) {
+ if(my_image->width() == width()) {
+ uchar *fb = (uchar*)my_painter->frameBuffer();
+ uchar *buf = (uchar*)my_image->bits();
+ if(rect == my_image->rect()) {
+ SDL_memcpy(fb, buf, width()*height()*2);
+ } else {
+ int h = rect.height();
+ int wd = rect.width()<<1;
+ int fblineadd = my_painter->lineStep();
+ int buflineadd = my_image->bytesPerLine();
+ fb += (rect.left()<<1) + rect.top() * my_painter->lineStep();
+ buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine();
+ while(h--) {
+ SDL_memcpy(fb, buf, wd);
+ fb += fblineadd;
+ buf += buflineadd;
+ }
+ }
+ } else {
+ return false; // FIXME: Landscape
+ }
+#ifdef __i386__
+ my_painter->fillRect( rect, QBrush( Qt::NoBrush ) );
+#endif
+ return true;
+}
+
+
+// Sharp Zaurus SL-5500 etc
+bool SDL_QWin::repaintRotation3(const QRect& rect) {
+ if(my_image->width() == width()) {
+ ushort *fb = (ushort*)my_painter->frameBuffer();
+ ushort *buf = (ushort*)my_image->bits();
+ gs_fastRotateBlit_3(fb, buf, rect);
+ } else {
+ // landscape mode
+ if (screenRotation == SDL_QT_ROTATION_90) {
+ uchar *fb = (uchar*)my_painter->frameBuffer();
+ uchar *buf = (uchar*)my_image->bits();
+ if(rect == my_image->rect()) {
+ SDL_memcpy(fb, buf, width()*height()*2);
+ } else {
+ int h = rect.height();
+ int wd = rect.width()<<1;
+ int fblineadd = my_painter->lineStep();
+ int buflineadd = my_image->bytesPerLine();
+ fb += (rect.left()<<1) + rect.top() * my_painter->lineStep();
+ buf += (rect.left()<<1) + rect.top() * my_image->bytesPerLine();
+ while(h--) {
+ SDL_memcpy(fb, buf, wd);
+ fb += fblineadd;
+ buf += buflineadd;
+ }
+ }
+ } else if (screenRotation == SDL_QT_ROTATION_270) {
+ int h = rect.height();
+ int wd = rect.width();
+ int fblineadd = my_painter->lineStep() - (rect.width() << 1);
+ int buflineadd = my_image->bytesPerLine() - (rect.width() << 1);
+ int w;
+
+ uchar *fb = (uchar*)my_painter->frameBuffer();
+ uchar *buf = (uchar*)my_image->bits();
+
+ fb += ((my_painter->width() - (rect.top() + rect.height())) *
+ my_painter->lineStep()) + ((my_painter->height() - ((rect.left() +
+ rect.width()))) << 1);
+
+ buf += my_image->bytesPerLine() * (rect.top() + rect.height()) -
+ (((my_image->width() - (rect.left() + rect.width())) << 1) + 2);
+
+ while(h--) {
+ w = wd;
+ while(w--) *((unsigned short*)fb)++ = *((unsigned short*)buf)--;
+ fb += fblineadd;
+ buf -= buflineadd;
+ }
+ }
+ }
+ return true;
+}
+
+// ipaq 3800...
+bool SDL_QWin::repaintRotation1(const QRect& rect) {
+ if(my_image->width() == width()) {
+ ushort *fb = (ushort*)my_painter->frameBuffer();
+ ushort *buf = (ushort*)my_image->bits();
+ gs_fastRotateBlit_1(fb, buf, rect);
+ } else {
+ return false; // FIXME: landscape mode
+ }
+ return true;
+}
+
+void SDL_QWin::repaintRect(const QRect& rect) {
+ if(!my_painter || !rect.width() || !rect.height()) {
+ return;
+ }
+
+ if(QPixmap::defaultDepth() == 16) {
+ switch(my_painter->transformOrientation()) {
+ case 3:
+ if(repaintRotation3(rect)) { return; }
+ break;
+ case 1:
+ if(repaintRotation1(rect)) { return; }
+ break;
+ case 0:
+ if(repaintRotation0(rect)) { return; }
+ break;
+ }
+ }
+ my_painter->drawImage(rect.topLeft(), *my_image, rect);
+}
+
+// This paints the current buffer to the screen, when desired.
+void SDL_QWin::paintEvent(QPaintEvent *ev) {
+ if(my_image) {
+ lockScreen(true);
+ repaintRect(ev->rect());
+ unlockScreen();
+ }
+}
+
+/* Function to translate a keyboard transition and queue the key event
+ * This should probably be a table although this method isn't exactly
+ * slow.
+ */
+void SDL_QWin::QueueKey(QKeyEvent *e, int pressed)
+{
+ SDL_keysym keysym;
+ int scancode = e->key();
+ /* Set the keysym information */
+ if(scancode >= 'A' && scancode <= 'Z') {
+ // Qt sends uppercase, SDL wants lowercase
+ keysym.sym = static_cast<SDLKey>(scancode + 32);
+ } else if(scancode >= 0x1000) {
+ // Special keys
+ switch(scancode) {
+ case Qt::Key_Escape: scancode = SDLK_ESCAPE; break;
+ case Qt::Key_Tab: scancode = SDLK_TAB; break;
+ case Qt::Key_Backspace: scancode = SDLK_BACKSPACE; break;
+ case Qt::Key_Return: scancode = SDLK_RETURN; break;
+ case Qt::Key_Enter: scancode = SDLK_KP_ENTER; break;
+ case Qt::Key_Insert: scancode = SDLK_INSERT; break;
+ case Qt::Key_Delete: scancode = SDLK_DELETE; break;
+ case Qt::Key_Pause: scancode = SDLK_PAUSE; break;
+ case Qt::Key_Print: scancode = SDLK_PRINT; break;
+ case Qt::Key_SysReq: scancode = SDLK_SYSREQ; break;
+ case Qt::Key_Home: scancode = SDLK_HOME; break;
+ case Qt::Key_End: scancode = SDLK_END; break;
+ // We want the control keys to rotate with the screen
+ case Qt::Key_Left:
+ if (screenRotation == SDL_QT_ROTATION_90) scancode = SDLK_UP;
+ else if (screenRotation == SDL_QT_ROTATION_270) scancode = SDLK_DOWN;
+ else scancode = SDLK_LEFT;
+ break;
+ case Qt::Key_Up:
+ if (screenRotation == SDL_QT_ROTATION_90) scancode = SDLK_RIGHT;
+ else if (screenRotation == SDL_QT_ROTATION_270) scancode = SDLK_LEFT;
+ else scancode = SDLK_UP;
+ break;
+ case Qt::Key_Right:
+ if (screenRotation == SDL_QT_ROTATION_90) scancode = SDLK_DOWN;
+ else if (screenRotation == SDL_QT_ROTATION_270) scancode = SDLK_UP;
+ else scancode = SDLK_RIGHT;
+ break;
+ case Qt::Key_Down:
+ if (screenRotation == SDL_QT_ROTATION_90) scancode = SDLK_LEFT;
+ else if (screenRotation == SDL_QT_ROTATION_270) scancode = SDLK_RIGHT;
+ else scancode = SDLK_DOWN;
+ break;
+ case Qt::Key_Prior: scancode = SDLK_PAGEUP; break;
+ case Qt::Key_Next: scancode = SDLK_PAGEDOWN; break;
+ case Qt::Key_Shift: scancode = SDLK_LSHIFT; break;
+ case Qt::Key_Control: scancode = SDLK_LCTRL; break;
+ case Qt::Key_Meta: scancode = SDLK_LMETA; break;
+ case Qt::Key_Alt: scancode = SDLK_LALT; break;
+ case Qt::Key_CapsLock: scancode = SDLK_CAPSLOCK; break;
+ case Qt::Key_NumLock: scancode = SDLK_NUMLOCK; break;
+ case Qt::Key_ScrollLock: scancode = SDLK_SCROLLOCK; break;
+ case Qt::Key_F1: scancode = SDLK_F1; break;
+ case Qt::Key_F2: scancode = SDLK_F2; break;
+ case Qt::Key_F3: scancode = SDLK_F3; break;
+ case Qt::Key_F4: scancode = SDLK_F4; break;
+ case Qt::Key_F5: scancode = SDLK_F5; break;
+ case Qt::Key_F6: scancode = SDLK_F6; break;
+ case Qt::Key_F7: scancode = SDLK_F7; break;
+ case Qt::Key_F8: scancode = SDLK_F8; break;
+ case Qt::Key_F9: scancode = SDLK_F9; break;
+ case Qt::Key_F10: scancode = SDLK_F10; break;
+ case Qt::Key_F11: scancode = SDLK_F11; break;
+ case Qt::Key_F12: scancode = SDLK_F12; break;
+ case Qt::Key_F13: scancode = SDLK_F13; break;
+ case Qt::Key_F14: scancode = SDLK_F14; break;
+ case Qt::Key_F15: scancode = SDLK_F15; break;
+ case Qt::Key_Super_L: scancode = SDLK_LSUPER; break;
+ case Qt::Key_Super_R: scancode = SDLK_RSUPER; break;
+ case Qt::Key_Menu: scancode = SDLK_MENU; break;
+ case Qt::Key_Help: scancode = SDLK_HELP; break;
+
+ case Qt::Key_F33:
+ // FIXME: This is a hack to enable the OK key on
+ // Zaurii devices. SDLK_RETURN is a suitable key to use
+ // since it often is used as such.
+ // david@hedbor.org
+ scancode = SDLK_RETURN;
+ break;
+ default:
+ scancode = SDLK_UNKNOWN;
+ break;
+ }
+ keysym.sym = static_cast<SDLKey>(scancode);
+ } else {
+ keysym.sym = static_cast<SDLKey>(scancode);
+ }
+ keysym.scancode = scancode;
+ keysym.mod = KMOD_NONE;
+ ButtonState st = e->state();
+ if( (st & ShiftButton) ) { keysym.mod = static_cast<SDLMod>(keysym.mod | KMOD_LSHIFT); }
+ if( (st & ControlButton) ) { keysym.mod = static_cast<SDLMod>(keysym.mod | KMOD_LCTRL); }
+ if( (st & AltButton) ) { keysym.mod = static_cast<SDLMod>(keysym.mod | KMOD_LALT); }
+ if ( SDL_TranslateUNICODE ) {
+ QChar qchar = e->text()[0];
+ keysym.unicode = qchar.unicode();
+ } else {
+ keysym.unicode = 0;
+ }
+
+ /* NUMLOCK and CAPSLOCK are implemented as double-presses in reality */
+ // if ( (keysym.sym == SDLK_NUMLOCK) || (keysym.sym == SDLK_CAPSLOCK) ) {
+ // pressed = 1;
+ // }
+
+ /* Queue the key event */
+ if ( pressed ) {
+ SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ } else {
+ SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+ }
+}
+
+void SDL_QWin::setFullscreen(bool fs_on) {
+ my_has_fullscreen = false;
+ enableFullscreen();
+}
+
+void SDL_QWin::enableFullscreen() {
+ // Make sure size is correct
+ if(!my_has_fullscreen) {
+ setFixedSize(qApp->desktop()->size());
+ // This call is needed because showFullScreen won't work
+ // correctly if the widget already considers itself to be fullscreen.
+ showNormal();
+ // This is needed because showNormal() forcefully changes the window
+ // style to WSTyle_TopLevel.
+ setWFlags(WStyle_Customize | WStyle_NoBorder);
+ // Enable fullscreen.
+ showFullScreen();
+ my_has_fullscreen = true;
+ }
+}
+
+bool SDL_QWin::lockScreen(bool force) {
+ if(!my_painter) {
+ if(force || (isVisible() && isActiveWindow())) {
+ my_painter = new QDirectPainter(this);
+ } else {
+ return false;
+ }
+ }
+ my_locked++; // Increate lock refcount
+ return true;
+}
+
+void SDL_QWin::unlockScreen() {
+ if(my_locked > 0) {
+ my_locked--; // decrease lock refcount;
+ }
+ if(!my_locked && my_painter) {
+ my_painter->end();
+ delete my_painter;
+ my_painter = 0;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.h
new file mode 100644
index 0000000..2531834
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_QWin.h
@@ -0,0 +1,110 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_QWin_h
+#define _SDL_QWin_h
+
+#include <stdio.h>
+
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qwidget.h>
+#include <qpainter.h>
+#include <qdirectpainter_qws.h>
+
+#include "SDL_events.h"
+
+extern "C" {
+#include "../../events/SDL_events_c.h"
+};
+
+typedef enum {
+ SDL_QT_NO_ROTATION = 0,
+ SDL_QT_ROTATION_90,
+ SDL_QT_ROTATION_270
+} screenRotationT;
+
+extern screenRotationT screenRotation;
+
+class SDL_QWin : public QWidget
+{
+ void QueueKey(QKeyEvent *e, int pressed);
+ public:
+ SDL_QWin(const QSize& size);
+ virtual ~SDL_QWin();
+ virtual bool shown(void) {
+ return isVisible();
+ }
+ /* If called, the next resize event will not be forwarded to SDL. */
+ virtual void inhibitResize(void) {
+ my_inhibit_resize = true;
+ }
+ void setImage(QImage *image);
+ void setOffset(int x, int y) {
+ my_offset = QPoint(x, y);
+ }
+ void GetXYOffset(int &x, int &y) {
+ x = my_offset.x();
+ y = my_offset.y();
+ }
+ QImage *image(void) { return my_image; }
+
+ void setWFlags(WFlags flags) {
+ QWidget::setWFlags(flags);
+ my_flags = flags;
+ }
+ const QPoint& mousePos() const { return my_mouse_pos; }
+ void setMousePos(const QPoint& newpos);
+ void setFullscreen(bool);
+
+ bool lockScreen(bool force=false);
+ void unlockScreen();
+ void repaintRect(const QRect& rect);
+ protected:
+ /* Handle resizing of the window */
+ virtual void resizeEvent(QResizeEvent *e);
+ void focusInEvent(QFocusEvent *);
+ void focusOutEvent(QFocusEvent *);
+ void closeEvent(QCloseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void paintEvent(QPaintEvent *ev);
+ void keyPressEvent(QKeyEvent *e) { QueueKey(e, 1); }
+ void keyReleaseEvent(QKeyEvent *e) { QueueKey(e, 0); }
+ private:
+ bool repaintRotation0(const QRect& rect);
+ bool repaintRotation1(const QRect& rect);
+ bool repaintRotation3(const QRect& rect);
+ void enableFullscreen();
+ QDirectPainter *my_painter;
+ QImage *my_image;
+ bool my_inhibit_resize;
+ QPoint my_offset;
+ QPoint my_mouse_pos;
+ WFlags my_flags;
+ WFlags my_has_fullscreen;
+ unsigned int my_locked;
+};
+
+#endif /* _SDL_QWin_h */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_lowvideo.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_lowvideo.h
new file mode 100644
index 0000000..1d05c72
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_lowvideo.h
@@ -0,0 +1,65 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_lowvideo_h
+#define _SDL_lowvideo_h
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *_this
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ /* The main window */
+ SDL_QWin *SDL_Win;
+
+ /* The fullscreen mode list */
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+ /* A completely clear cursor */
+ WMcursor *BlankCursor;
+
+ /* Mouse state variables */
+ Uint32 last_buttons;
+ QPoint last_point;
+
+ /* Keyboard state variables */
+ int key_flip;
+ //struct key_info keyinfo[2];
+};
+/* Old variable names */
+#define SDL_Win (_this->hidden->SDL_Win)
+#define saved_mode (_this->hidden->saved_mode)
+#define SDL_nummodes (_this->hidden->SDL_nummodes)
+#define SDL_modelist (_this->hidden->SDL_modelist)
+#define SDL_BlankCursor (_this->hidden->BlankCursor)
+#define last_buttons (_this->hidden->last_buttons)
+#define last_point (_this->hidden->last_point)
+#define key_flip (_this->hidden->key_flip)
+#define keyinfo (_this->hidden->keyinfo)
+
+#endif /* _SDL_lowvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents.cc
new file mode 100644
index 0000000..4aaf814
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents.cc
@@ -0,0 +1,269 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <qpe/qpeapplication.h>
+
+#include <stdio.h>
+#include <string.h>
+#include "SDL_error.h"
+#include "SDL_events.h"
+#include "SDL_QWin.h"
+#include "SDL_lowvideo.h"
+#include "SDL_timer.h"
+
+extern "C" {
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_sysevents_c.h"
+
+ // static SDLKey keymap[128];
+/* This is special because we know it will be run in a loop in a separate
+ thread. Normally this function should loop as long as there are input
+ states changing, i.e. new events arriving.
+*/
+void QT_PumpEvents(_THIS)
+{
+ if(!qApp) {
+ return;
+ }
+ // printf("processing events: %p\n", qApp);
+ //qApp->processOneEvent(); // wait for a event
+ qApp->processEvents(); // and process all outstanding ones
+#if 0
+ BView *view;
+ BRect bounds;
+ BPoint point;
+ uint32 buttons;
+ const uint32 button_masks[3] = {
+ B_PRIMARY_MOUSE_BUTTON,
+ B_TERTIARY_MOUSE_BUTTON,
+ B_SECONDARY_MOUSE_BUTTON,
+ };
+ unsigned int i, j;
+
+ /* Check out the mouse buttons and position (slight race condition) */
+ if ( SDL_Win->Lock() ) {
+ /* Don't do anything if we have no view */
+ view = SDL_Win->View();
+ if ( ! view ) {
+ SDL_Win->Unlock();
+ return;
+ }
+ bounds = view->Bounds();
+ /* Get new input state, if still active */
+ if ( SDL_Win->IsActive() ) {
+ key_flip = !key_flip;
+ get_key_info(&keyinfo[key_flip]);
+ view->GetMouse(&point, &buttons, true);
+ } else {
+ key_flip = key_flip;
+ point = last_point;
+ buttons = last_buttons;
+ }
+ SDL_Win->Unlock();
+ } else {
+ return;
+ }
+
+ /* If our view is active, we'll find key changes here */
+ if ( SDL_memcmp(keyinfo[0].key_states, keyinfo[1].key_states, 16) != 0 ) {
+ for ( i=0; i<16; ++i ) {
+ Uint8 new_state, transition;
+
+ new_state = keyinfo[key_flip].key_states[i];
+ transition = keyinfo[!key_flip].key_states[i] ^
+ keyinfo[ key_flip].key_states[i];
+ for ( j=0; j<8; ++j ) {
+ if ( transition&0x80 )
+ QueueKey(i*8+j, new_state&0x80);
+ transition <<= 1;
+ new_state <<= 1;
+ }
+ }
+ }
+
+ /* We check keyboard, but not mouse if mouse isn't in window */
+ if ( ! bounds.Contains(point) ) {
+ /* Mouse moved outside our view? */
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ be_app->SetCursor(B_HAND_CURSOR);
+ }
+ return;
+ }
+ /* Has the mouse moved back into our view? */
+ if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ /* Reset the B_HAND_CURSOR to our own */
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ SDL_SetCursor(NULL);
+ }
+
+ /* Check for mouse motion */
+ if ( point != last_point ) {
+ int x, y;
+
+ SDL_Win->GetXYOffset(x, y);
+ x = (int)point.x - x;
+ y = (int)point.y - y;
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ }
+ last_point = point;
+
+ /* Add any mouse button events */
+ for ( i=0; i<SDL_TABLESIZE(button_masks); ++i ) {
+ if ( (buttons ^ last_buttons) & button_masks[i] ) {
+ if ( buttons & button_masks[i] ) {
+ SDL_PrivateMouseButton(SDL_PRESSED, 1+i, 0, 0);
+ } else {
+ SDL_PrivateMouseButton(SDL_RELEASED, 1+i, 0, 0);
+ }
+ }
+ }
+ last_buttons = buttons;
+#endif
+}
+
+void QT_InitOSKeymap(_THIS)
+{
+#if 0
+ unsigned int i;
+
+ /* Initialize all the key states as "up" */
+ key_flip = 0;
+ SDL_memset(keyinfo[key_flip].key_states, 0, 16);
+
+ /* Initialize the key translation table */
+ for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ // keymap[0x01] = SDLK_ESCAPE;
+ // keymap[B_F1_KEY] = SDLK_F1;
+ // keymap[B_F2_KEY] = SDLK_F2;
+ // keymap[B_F3_KEY] = SDLK_F3;
+ // keymap[B_F4_KEY] = SDLK_F4;
+ // keymap[B_F5_KEY] = SDLK_F5;
+ // keymap[B_F6_KEY] = SDLK_F6;
+ // keymap[B_F7_KEY] = SDLK_F7;
+ // keymap[B_F8_KEY] = SDLK_F8;
+ // keymap[B_F9_KEY] = SDLK_F9;
+ // keymap[B_F10_KEY] = SDLK_F10;
+ // keymap[B_F11_KEY] = SDLK_F11;
+ // keymap[B_F12_KEY] = SDLK_F12;
+ // keymap[B_PRINT_KEY] = SDLK_PRINT;
+ //keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK;
+ // keymap[B_PAUSE_KEY] = SDLK_PAUSE;
+ keymap[0x11] = SDLK_BACKQUOTE;
+ keymap[0x12] = SDLK_1;
+ keymap[0x13] = SDLK_2;
+ keymap[0x14] = SDLK_3;
+ keymap[0x15] = SDLK_4;
+ keymap[0x16] = SDLK_5;
+ keymap[0x17] = SDLK_6;
+ keymap[0x18] = SDLK_7;
+ keymap[0x19] = SDLK_8;
+ keymap[0x1a] = SDLK_9;
+ keymap[0x1b] = SDLK_0;
+ keymap[0x1c] = SDLK_MINUS;
+ keymap[0x1d] = SDLK_EQUALS;
+ keymap[0x1e] = SDLK_BACKSPACE;
+ keymap[0x1f] = SDLK_INSERT;
+ keymap[0x20] = SDLK_HOME;
+ keymap[0x21] = SDLK_PAGEUP;
+ //keymap[0x22] = SDLK_NUMLOCK;
+ keymap[0x23] = SDLK_KP_DIVIDE;
+ keymap[0x24] = SDLK_KP_MULTIPLY;
+ keymap[0x25] = SDLK_KP_MINUS;
+ keymap[0x26] = SDLK_TAB;
+ keymap[0x27] = SDLK_q;
+ keymap[0x28] = SDLK_w;
+ keymap[0x29] = SDLK_e;
+ keymap[0x2a] = SDLK_r;
+ keymap[0x2b] = SDLK_t;
+ keymap[0x2c] = SDLK_y;
+ keymap[0x2d] = SDLK_u;
+ keymap[0x2e] = SDLK_i;
+ keymap[0x2f] = SDLK_o;
+ keymap[0x30] = SDLK_p;
+ keymap[0x31] = SDLK_LEFTBRACKET;
+ keymap[0x32] = SDLK_RIGHTBRACKET;
+ keymap[0x33] = SDLK_BACKSLASH;
+ keymap[0x34] = SDLK_DELETE;
+ keymap[0x35] = SDLK_END;
+ keymap[0x36] = SDLK_PAGEDOWN;
+ keymap[0x37] = SDLK_KP7;
+ keymap[0x38] = SDLK_KP8;
+ keymap[0x39] = SDLK_KP9;
+ keymap[0x3a] = SDLK_KP_PLUS;
+ //keymap[0x3b] = SDLK_CAPSLOCK;
+ keymap[0x3c] = SDLK_a;
+ keymap[0x3d] = SDLK_s;
+ keymap[0x3e] = SDLK_d;
+ keymap[0x3f] = SDLK_f;
+ keymap[0x40] = SDLK_g;
+ keymap[0x41] = SDLK_h;
+ keymap[0x42] = SDLK_j;
+ keymap[0x43] = SDLK_k;
+ keymap[0x44] = SDLK_l;
+ keymap[0x45] = SDLK_SEMICOLON;
+ keymap[0x46] = SDLK_QUOTE;
+ keymap[0x47] = SDLK_RETURN;
+ keymap[0x48] = SDLK_KP4;
+ keymap[0x49] = SDLK_KP5;
+ keymap[0x4a] = SDLK_KP6;
+ keymap[0x4b] = SDLK_LSHIFT;
+ keymap[0x4c] = SDLK_z;
+ keymap[0x4d] = SDLK_x;
+ keymap[0x4e] = SDLK_c;
+ keymap[0x4f] = SDLK_v;
+ keymap[0x50] = SDLK_b;
+ keymap[0x51] = SDLK_n;
+ keymap[0x52] = SDLK_m;
+ keymap[0x53] = SDLK_COMMA;
+ keymap[0x54] = SDLK_PERIOD;
+ keymap[0x55] = SDLK_SLASH;
+ keymap[0x56] = SDLK_RSHIFT;
+ keymap[0x57] = SDLK_UP;
+ keymap[0x58] = SDLK_KP1;
+ keymap[0x59] = SDLK_KP2;
+ keymap[0x5a] = SDLK_KP3;
+ keymap[0x5b] = SDLK_KP_ENTER;
+ //keymap[0x5c] = SDLK_LCTRL;
+ //keymap[0x5d] = SDLK_LALT;
+ keymap[0x5e] = SDLK_SPACE;
+ //keymap[0x5f] = SDLK_RALT;
+ //keymap[0x60] = SDLK_RCTRL;
+ keymap[0x61] = SDLK_LEFT;
+ keymap[0x62] = SDLK_DOWN;
+ keymap[0x63] = SDLK_RIGHT;
+ keymap[0x64] = SDLK_KP0;
+ keymap[0x65] = SDLK_KP_PERIOD;
+ //keymap[0x66] = SDLK_LMETA;
+ //keymap[0x67] = SDLK_RMETA;
+ //keymap[0x68] = SDLK_MENU;
+ keymap[0x69] = SDLK_EURO;
+ keymap[0x6a] = SDLK_KP_EQUALS;
+ keymap[0x6b] = SDLK_POWER;
+#endif
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents_c.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents_c.h
new file mode 100644
index 0000000..5e26759
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysevents_c.h
@@ -0,0 +1,31 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+
+extern void QT_InitOSKeymap(_THIS);
+extern void QT_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse.cc
new file mode 100644
index 0000000..1a655b6
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse.cc
@@ -0,0 +1,56 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QWin.h"
+
+extern "C" {
+
+#include "SDL_sysmouse_c.h"
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ char *bits;
+};
+WMcursor *QT_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ static WMcursor dummy;
+ dummy.bits = 0;
+ return &dummy;
+}
+
+int QT_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ return 1;
+}
+
+void QT_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+}
+
+void QT_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ SDL_Win->setMousePos(QPoint(x, y));
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse_c.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse_c.h
new file mode 100644
index 0000000..98e4cf5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysmouse_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Functions to be exported */
+extern void QT_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *QT_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int QT_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void QT_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysvideo.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysvideo.cc
new file mode 100644
index 0000000..0e07874
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_sysvideo.cc
@@ -0,0 +1,403 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Qtopia based framebuffer implementation */
+
+#include <unistd.h>
+
+#include <qapplication.h>
+#include <qpe/qpeapplication.h>
+
+#include "SDL_timer.h"
+
+#include "SDL_QWin.h"
+
+extern "C" {
+
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_sysevents_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_lowvideo.h"
+
+ //#define QTOPIA_DEBUG
+#define QT_HIDDEN_SIZE 32 /* starting hidden window size */
+
+ /* Name of the environment variable used to invert the screen rotation or not:
+ Possible values:
+ !=0 : Screen is 270° rotated
+ 0: Screen is 90° rotated*/
+#define SDL_QT_ROTATION_ENV_NAME "SDL_QT_INVERT_ROTATION"
+
+ /* Initialization/Query functions */
+ static int QT_VideoInit(_THIS, SDL_PixelFormat *vformat);
+ static SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+ static SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+ static void QT_UpdateMouse(_THIS);
+ static int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+ static void QT_VideoQuit(_THIS);
+
+ /* Hardware surface functions */
+ static int QT_AllocHWSurface(_THIS, SDL_Surface *surface);
+ static int QT_LockHWSurface(_THIS, SDL_Surface *surface);
+ static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface);
+ static void QT_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+ static int QT_ToggleFullScreen(_THIS, int fullscreen);
+
+ static int QT_IconifyWindow(_THIS);
+ static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode);
+
+ /* FB driver bootstrap functions */
+
+ static int QT_Available(void)
+ {
+ return(1);
+ }
+
+ static void QT_DeleteDevice(SDL_VideoDevice *device)
+ {
+ SDL_free(device->hidden);
+ SDL_free(device);
+ }
+
+ static SDL_VideoDevice *QT_CreateDevice(int devindex)
+ {
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = QT_VideoInit;
+ device->ListModes = QT_ListModes;
+ device->SetVideoMode = QT_SetVideoMode;
+ device->UpdateMouse = QT_UpdateMouse;
+ device->SetColors = QT_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = QT_VideoQuit;
+ device->AllocHWSurface = QT_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = QT_LockHWSurface;
+ device->UnlockHWSurface = QT_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = QT_FreeHWSurface;
+ device->SetIcon = NULL;
+ device->SetCaption = QT_SetWMCaption;
+ device->IconifyWindow = QT_IconifyWindow;
+ device->GrabInput = QT_GrabInput;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = QT_FreeWMCursor;
+ device->CreateWMCursor = QT_CreateWMCursor;
+ device->ShowWMCursor = QT_ShowWMCursor;
+ device->WarpWMCursor = QT_WarpWMCursor;
+ device->InitOSKeymap = QT_InitOSKeymap;
+ device->PumpEvents = QT_PumpEvents;
+
+ device->free = QT_DeleteDevice;
+ device->ToggleFullScreen = QT_ToggleFullScreen;
+
+ /* Set the driver flags */
+ device->handles_any_size = 0;
+
+ return device;
+ }
+
+ VideoBootStrap Qtopia_bootstrap = {
+ "qtopia", "Qtopia / QPE graphics",
+ QT_Available, QT_CreateDevice
+ };
+
+ /* Function to sort the display_list */
+ static int CompareModes(const void *A, const void *B)
+ {
+#if 0
+ const display_mode *a = (display_mode *)A;
+ const display_mode *b = (display_mode *)B;
+
+ if ( a->space == b->space ) {
+ return((b->virtual_width*b->virtual_height)-
+ (a->virtual_width*a->virtual_height));
+ } else {
+ return(ColorSpaceToBitsPerPixel(b->space)-
+ ColorSpaceToBitsPerPixel(a->space));
+ }
+#endif
+ return 0;
+ }
+
+ /* Yes, this isn't the fastest it could be, but it works nicely */
+ static int QT_AddMode(_THIS, int index, unsigned int w, unsigned int h)
+ {
+ SDL_Rect *mode;
+ int i;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( SDL_nummodes[index] > 0 ) {
+ for ( i=SDL_nummodes[index]-1; i >= 0; --i ) {
+ mode = SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+#ifdef QTOPIA_DEBUG
+ fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1);
+#endif
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+ }
+
+ int QT_VideoInit(_THIS, SDL_PixelFormat *vformat)
+ {
+ /* Initialize the QPE Application */
+ /* Determine the screen depth */
+ vformat->BitsPerPixel = QPixmap::defaultDepth();
+
+ // For now we hardcode the current depth because anything else
+ // might as well be emulated by SDL rather than by Qtopia.
+
+ QSize desktop_size = qApp->desktop()->size();
+ QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1,
+ desktop_size.width(), desktop_size.height());
+ QT_AddMode(_this, ((vformat->BitsPerPixel+7)/8)-1,
+ desktop_size.height(), desktop_size.width());
+
+ /* Determine the current screen size */
+ _this->info.current_w = desktop_size.width();
+ _this->info.current_h = desktop_size.height();
+
+ /* Create the window / widget */
+ SDL_Win = new SDL_QWin(QSize(QT_HIDDEN_SIZE, QT_HIDDEN_SIZE));
+ ((QPEApplication*)qApp)->showMainWidget(SDL_Win);
+ /* Fill in some window manager capabilities */
+ _this->info.wm_available = 0;
+
+ /* We're done! */
+ return(0);
+ }
+
+ /* We support any dimension at our bit-depth */
+ SDL_Rect **QT_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+ {
+ SDL_Rect **modes;
+
+ modes = ((SDL_Rect **)0);
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ modes = SDL_modelist[((format->BitsPerPixel+7)/8)-1];
+ } else {
+ if ( format->BitsPerPixel ==
+ _this->screen->format->BitsPerPixel ) {
+ modes = ((SDL_Rect **)-1);
+ }
+ }
+ return(modes);
+ }
+
+ /* Various screen update functions available */
+ static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+
+ static int QT_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
+ {
+ return -1;
+ }
+
+ static int QT_ToggleFullScreen(_THIS, int fullscreen)
+ {
+ return -1;
+ }
+
+ /* FIXME: check return values and cleanup here */
+ SDL_Surface *QT_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+ {
+
+ QImage *qimage;
+ QSize desktop_size = qApp->desktop()->size();
+
+
+ current->flags = 0; //SDL_FULLSCREEN; // We always run fullscreen.
+
+ if(width <= desktop_size.width()
+ && height <= desktop_size.height()) {
+ current->w = desktop_size.width();
+ current->h = desktop_size.height();
+ } else if(width <= desktop_size.height() && height <= desktop_size.width()) {
+ // Landscape mode
+ char * envString = SDL_getenv(SDL_QT_ROTATION_ENV_NAME);
+ int envValue = envString ? atoi(envString) : 0;
+ screenRotation = envValue ? SDL_QT_ROTATION_270 : SDL_QT_ROTATION_90;
+ current->h = desktop_size.width();
+ current->w = desktop_size.height();
+ } else {
+ SDL_SetError("Unsupported resolution, %dx%d\n", width, height);
+ }
+ if ( flags & SDL_OPENGL ) {
+ SDL_SetError("OpenGL not supported");
+ return(NULL);
+ }
+ /* Create the QImage framebuffer */
+ qimage = new QImage(current->w, current->h, bpp);
+ if (qimage->isNull()) {
+ SDL_SetError("Couldn't create screen bitmap");
+ delete qimage;
+ return(NULL);
+ }
+ current->pitch = qimage->bytesPerLine();
+ current->pixels = (void *)qimage->bits();
+ SDL_Win->setImage(qimage);
+ _this->UpdateRects = QT_NormalUpdate;
+ SDL_Win->setFullscreen(true);
+ /* We're done */
+ return(current);
+ }
+
+ /* Update the current mouse state and position */
+ void QT_UpdateMouse(_THIS)
+ {
+ QPoint point(-1, -1);
+ if ( SDL_Win->isActiveWindow() ) {
+ point = SDL_Win->mousePos();
+ }
+
+ if ( (point.x() >= 0) && (point.x() < SDL_VideoSurface->w) &&
+ (point.y() >= 0) && (point.y() < SDL_VideoSurface->h) ) {
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ SDL_PrivateMouseMotion(0, 0,
+ (Sint16)point.x(), (Sint16)point.y());
+ } else {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+ }
+
+ /* We don't actually allow hardware surfaces other than the main one */
+ static int QT_AllocHWSurface(_THIS, SDL_Surface *surface)
+ {
+ return(-1);
+ }
+ static void QT_FreeHWSurface(_THIS, SDL_Surface *surface)
+ {
+ return;
+ }
+ static int QT_LockHWSurface(_THIS, SDL_Surface *surface)
+ {
+ return(0);
+ }
+ static void QT_UnlockHWSurface(_THIS, SDL_Surface *surface)
+ {
+ return;
+ }
+
+ static void QT_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
+ {
+ if(SDL_Win->lockScreen()) {
+ for(int i=0; i<numrects; ++i ) {
+ QRect rect(rects[i].x, rects[i].y,
+ rects[i].w, rects[i].h);
+ SDL_Win->repaintRect(rect);
+ }
+ SDL_Win->unlockScreen();
+ }
+ }
+ /* Is the system palette settable? */
+ int QT_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+ {
+ return -1;
+ }
+
+ void QT_VideoQuit(_THIS)
+ {
+ // This is dumb, but if I free this, the app doesn't exit correctly.
+ // Of course, this will leak memory if init video is done more than once.
+ // Sucks but such is life.
+
+ // -- David Hedbor
+ // delete SDL_Win;
+ // SDL_Win = 0;
+ _this->screen->pixels = NULL;
+ QT_GrabInput(_this, SDL_GRAB_OFF);
+ }
+
+ static int QT_IconifyWindow(_THIS) {
+ SDL_Win->hide();
+
+ return true;
+ }
+
+ static SDL_GrabMode QT_GrabInput(_THIS, SDL_GrabMode mode) {
+ if(mode == SDL_GRAB_OFF) {
+ QPEApplication::grabKeyboard();
+ qApp->processEvents();
+ QPEApplication::ungrabKeyboard();
+ } else {
+ QPEApplication::grabKeyboard();
+ }
+ qApp->processEvents();
+ return mode;
+ }
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm.cc b/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm.cc
new file mode 100644
index 0000000..47f988f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm.cc
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QWin.h"
+
+extern "C" {
+
+#include "SDL_syswm_c.h"
+
+void QT_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_Win->setCaption(title);
+}
+
+}; /* Extern C */
diff --git a/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm_c.h b/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm_c.h
new file mode 100644
index 0000000..4e4326b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/qtopia/SDL_syswm_c.h
@@ -0,0 +1,28 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Functions to be exported */
+extern void QT_SetWMCaption(_THIS, const char *title, const char *icon);
+
diff --git a/distrib/sdl-1.2.15/src/video/quartz/CGS.h b/distrib/sdl-1.2.15/src/video/quartz/CGS.h
new file mode 100644
index 0000000..abe47f7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/CGS.h
@@ -0,0 +1,84 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Obscuring code: maximum number of windows above ours (inclusive)
+
+ Note: this doesn't work too well in practice and should be
+ phased out when we add OpenGL 2D acceleration. It was never
+ enabled in the first place, so this shouldn't be a problem ;-)
+*/
+#define kMaxWindows 256
+
+/* Some of the Core Graphics Server API for obscuring code */
+#define kCGSWindowLevelTop 2147483632
+#define kCGSWindowLevelDockIconDrag 500
+#define kCGSWindowLevelDockMenu 101
+#define kCGSWindowLevelMenuIgnore 21
+#define kCGSWindowLevelMenu 20
+#define kCGSWindowLevelDockLabel 12
+#define kCGSWindowLevelDockIcon 11
+#define kCGSWindowLevelDock 10
+#define kCGSWindowLevelUtility 3
+#define kCGSWindowLevelNormal 0
+
+/*
+ For completeness; We never use these window levels, they are always below us
+ #define kCGSWindowLevelMBarShadow -20
+ #define kCGSWindowLevelDesktopPicture -2147483647
+ #define kCGSWindowLevelDesktop -2147483648
+*/
+
+typedef CGError CGSError;
+typedef long CGSWindowCount;
+typedef void * CGSConnectionID;
+typedef int CGSWindowID;
+typedef CGSWindowID* CGSWindowIDList;
+typedef CGWindowLevel CGSWindowLevel;
+typedef NSRect CGSRect;
+
+extern CGSConnectionID _CGSDefaultConnection ();
+
+extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
+ CGSConnectionID owner,
+ CGSWindowCount listCapacity,
+ CGSWindowIDList list,
+ CGSWindowCount *listCount);
+
+extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
+ CGSWindowID wid,
+ CGSRect *rect);
+
+extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
+ CGSWindowID wid,
+ CGSWindowLevel *level);
+
+extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
+ unsigned int w, unsigned int h, unsigned int color);
+
+extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
+
+extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
+
+int CGSDisplayHWSync (CGDirectDisplayID id);
+
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzEvents.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzEvents.m
new file mode 100644
index 0000000..773eb01
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzEvents.m
@@ -0,0 +1,1063 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWM.h"
+
+#include <IOKit/IOMessage.h> /* For wake from sleep detection */
+#include <IOKit/pwr_mgt/IOPMLib.h> /* For wake from sleep detection */
+#include "SDL_QuartzKeys.h"
+
+/*
+ * On Leopard, this is missing from the 64-bit headers
+ */
+#if defined(__LP64__) && !defined(__POWER__)
+/*
+ * Workaround for a bug in the 10.5 SDK: By accident, OSService.h does
+ * not include Power.h at all when compiling in 64bit mode. This has
+ * been fixed in 10.6, but for 10.5, we manually define UsrActivity
+ * to ensure compilation works.
+ */
+#define UsrActivity 1
+#endif
+
+/*
+ * In Panther, this header defines device dependent masks for
+ * right side keys. These definitions only exist in Panther, but
+ * the header seems to exist at least in Jaguar and probably earlier
+ * versions of the OS, so this should't break anything.
+ */
+#include <IOKit/hidsystem/IOLLEvent.h>
+/*
+ * These are not defined before Panther. To keep the code compiling
+ * on systems without these, I will define if they don't exist.
+ */
+#ifndef NX_DEVICERCTLKEYMASK
+ #define NX_DEVICELCTLKEYMASK 0x00000001
+#endif
+#ifndef NX_DEVICELSHIFTKEYMASK
+ #define NX_DEVICELSHIFTKEYMASK 0x00000002
+#endif
+#ifndef NX_DEVICERSHIFTKEYMASK
+ #define NX_DEVICERSHIFTKEYMASK 0x00000004
+#endif
+#ifndef NX_DEVICELCMDKEYMASK
+ #define NX_DEVICELCMDKEYMASK 0x00000008
+#endif
+#ifndef NX_DEVICERCMDKEYMASK
+ #define NX_DEVICERCMDKEYMASK 0x00000010
+#endif
+#ifndef NX_DEVICELALTKEYMASK
+ #define NX_DEVICELALTKEYMASK 0x00000020
+#endif
+#ifndef NX_DEVICERALTKEYMASK
+ #define NX_DEVICERALTKEYMASK 0x00000040
+#endif
+#ifndef NX_DEVICERCTLKEYMASK
+ #define NX_DEVICERCTLKEYMASK 0x00002000
+#endif
+
+void QZ_InitOSKeymap (_THIS) {
+ BOOL saw_layout = NO;
+ UInt32 state;
+ UInt32 value;
+ Uint16 i;
+ int world = SDLK_WORLD_0;
+
+ for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ /* This keymap is almost exactly the same as the OS 9 one */
+ keymap[QZ_ESCAPE] = SDLK_ESCAPE;
+ keymap[QZ_F1] = SDLK_F1;
+ keymap[QZ_F2] = SDLK_F2;
+ keymap[QZ_F3] = SDLK_F3;
+ keymap[QZ_F4] = SDLK_F4;
+ keymap[QZ_F5] = SDLK_F5;
+ keymap[QZ_F6] = SDLK_F6;
+ keymap[QZ_F7] = SDLK_F7;
+ keymap[QZ_F8] = SDLK_F8;
+ keymap[QZ_F9] = SDLK_F9;
+ keymap[QZ_F10] = SDLK_F10;
+ keymap[QZ_F11] = SDLK_F11;
+ keymap[QZ_F12] = SDLK_F12;
+ keymap[QZ_F13] = SDLK_F13;
+ keymap[QZ_F14] = SDLK_F14;
+ keymap[QZ_F15] = SDLK_F15;
+/*
+ keymap[QZ_PRINT] = SDLK_PRINT;
+ keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
+ keymap[QZ_PAUSE] = SDLK_PAUSE;
+*/
+ keymap[QZ_POWER] = SDLK_POWER;
+ keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
+ keymap[QZ_1] = SDLK_1;
+ keymap[QZ_2] = SDLK_2;
+ keymap[QZ_3] = SDLK_3;
+ keymap[QZ_4] = SDLK_4;
+ keymap[QZ_5] = SDLK_5;
+ keymap[QZ_6] = SDLK_6;
+ keymap[QZ_7] = SDLK_7;
+ keymap[QZ_8] = SDLK_8;
+ keymap[QZ_9] = SDLK_9;
+ keymap[QZ_0] = SDLK_0;
+ keymap[QZ_MINUS] = SDLK_MINUS;
+ keymap[QZ_EQUALS] = SDLK_EQUALS;
+ keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
+ keymap[QZ_INSERT] = SDLK_INSERT;
+ keymap[QZ_HOME] = SDLK_HOME;
+ keymap[QZ_PAGEUP] = SDLK_PAGEUP;
+ keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
+ keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
+ keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
+ keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
+ keymap[QZ_TAB] = SDLK_TAB;
+ keymap[QZ_q] = SDLK_q;
+ keymap[QZ_w] = SDLK_w;
+ keymap[QZ_e] = SDLK_e;
+ keymap[QZ_r] = SDLK_r;
+ keymap[QZ_t] = SDLK_t;
+ keymap[QZ_y] = SDLK_y;
+ keymap[QZ_u] = SDLK_u;
+ keymap[QZ_i] = SDLK_i;
+ keymap[QZ_o] = SDLK_o;
+ keymap[QZ_p] = SDLK_p;
+ keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
+ keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
+ keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
+ keymap[QZ_DELETE] = SDLK_DELETE;
+ keymap[QZ_END] = SDLK_END;
+ keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
+ keymap[QZ_KP7] = SDLK_KP7;
+ keymap[QZ_KP8] = SDLK_KP8;
+ keymap[QZ_KP9] = SDLK_KP9;
+ keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
+ keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
+ keymap[QZ_a] = SDLK_a;
+ keymap[QZ_s] = SDLK_s;
+ keymap[QZ_d] = SDLK_d;
+ keymap[QZ_f] = SDLK_f;
+ keymap[QZ_g] = SDLK_g;
+ keymap[QZ_h] = SDLK_h;
+ keymap[QZ_j] = SDLK_j;
+ keymap[QZ_k] = SDLK_k;
+ keymap[QZ_l] = SDLK_l;
+ keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
+ keymap[QZ_QUOTE] = SDLK_QUOTE;
+ keymap[QZ_RETURN] = SDLK_RETURN;
+ keymap[QZ_KP4] = SDLK_KP4;
+ keymap[QZ_KP5] = SDLK_KP5;
+ keymap[QZ_KP6] = SDLK_KP6;
+ keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
+ keymap[QZ_LSHIFT] = SDLK_LSHIFT;
+ keymap[QZ_RSHIFT] = SDLK_RSHIFT;
+ keymap[QZ_z] = SDLK_z;
+ keymap[QZ_x] = SDLK_x;
+ keymap[QZ_c] = SDLK_c;
+ keymap[QZ_v] = SDLK_v;
+ keymap[QZ_b] = SDLK_b;
+ keymap[QZ_n] = SDLK_n;
+ keymap[QZ_m] = SDLK_m;
+ keymap[QZ_COMMA] = SDLK_COMMA;
+ keymap[QZ_PERIOD] = SDLK_PERIOD;
+ keymap[QZ_SLASH] = SDLK_SLASH;
+ keymap[QZ_UP] = SDLK_UP;
+ keymap[QZ_KP1] = SDLK_KP1;
+ keymap[QZ_KP2] = SDLK_KP2;
+ keymap[QZ_KP3] = SDLK_KP3;
+ keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
+ keymap[QZ_LCTRL] = SDLK_LCTRL;
+ keymap[QZ_LALT] = SDLK_LALT;
+ keymap[QZ_LMETA] = SDLK_LMETA;
+ keymap[QZ_RCTRL] = SDLK_RCTRL;
+ keymap[QZ_RALT] = SDLK_RALT;
+ keymap[QZ_RMETA] = SDLK_RMETA;
+ keymap[QZ_SPACE] = SDLK_SPACE;
+ keymap[QZ_LEFT] = SDLK_LEFT;
+ keymap[QZ_DOWN] = SDLK_DOWN;
+ keymap[QZ_RIGHT] = SDLK_RIGHT;
+ keymap[QZ_KP0] = SDLK_KP0;
+ keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
+ keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
+ keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
+ keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
+ keymap[QZ_IBOOK_UP] = SDLK_UP;
+ keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
+
+ /*
+ Up there we setup a static scancode->keysym map. However, it will not
+ work very well on international keyboard. Hence we now query MacOS
+ for its own keymap to adjust our own mapping table. However, this is
+ basically only useful for ascii char keys. This is also the reason
+ why we keep the static table, too.
+ */
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1050)
+ if (TISCopyCurrentKeyboardLayoutInputSource != NULL) {
+ TISInputSourceRef src = TISCopyCurrentKeyboardLayoutInputSource();
+ if (src != NULL) {
+ CFDataRef data = (CFDataRef)
+ TISGetInputSourceProperty(src,
+ kTISPropertyUnicodeKeyLayoutData);
+ if (data != NULL) {
+ const UCKeyboardLayout *layout = (const UCKeyboardLayout *)
+ CFDataGetBytePtr(data);
+ if (layout != NULL) {
+ const UInt32 kbdtype = LMGetKbdType();
+ saw_layout = YES;
+
+ /* Loop over all 127 possible scan codes */
+ for (i = 0; i < 0x7F; i++) {
+ UniChar buf[16];
+ UniCharCount count = 0;
+
+ /* We pretend a clean start to begin with (i.e. no dead keys active */
+ state = 0;
+
+ if (UCKeyTranslate(layout, i, kUCKeyActionDown, 0, kbdtype,
+ 0, &state, 16, &count, buf) != noErr) {
+ continue;
+ }
+
+ /* If the state become 0, it was a dead key. We need to
+ translate again, passing in the new state, to get
+ the actual key value */
+ if (state != 0) {
+ if (UCKeyTranslate(layout, i, kUCKeyActionDown, 0, kbdtype,
+ 0, &state, 16, &count, buf) != noErr) {
+ continue;
+ }
+ }
+
+ if (count != 1) {
+ continue; /* no multi-char. Use SDL 1.3 instead. :) */
+ }
+
+ value = (UInt32) buf[0];
+ if (value >= 128) {
+ /* Some non-ASCII char, map it to SDLK_WORLD_* */
+ if (world < 0xFF) {
+ keymap[i] = world++;
+ }
+ } else if (value >= 32) { /* non-control ASCII char */
+ keymap[i] = value;
+ }
+ }
+ }
+ }
+ CFRelease(src);
+ }
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1050)
+ if (!saw_layout) {
+ /* Get a pointer to the systems cached KCHR */
+ const void *KCHRPtr = (const void *)GetScriptManagerVariable(smKCHRCache);
+ if (KCHRPtr)
+ {
+ /* Loop over all 127 possible scan codes */
+ for (i = 0; i < 0x7F; i++)
+ {
+ /* We pretend a clean start to begin with (i.e. no dead keys active */
+ state = 0;
+
+ /* Now translate the key code to a key value */
+ value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
+
+ /* If the state become 0, it was a dead key. We need to translate again,
+ passing in the new state, to get the actual key value */
+ if (state != 0)
+ value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
+
+ /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
+ if (value >= 128) { /* Some non-ASCII char, map it to SDLK_WORLD_* */
+ if (world < 0xFF) {
+ keymap[i] = world++;
+ }
+ } else if (value >= 32) { /* non-control ASCII char */
+ keymap[i] = value;
+ }
+ }
+ }
+ }
+#endif
+
+ /*
+ The keypad codes are re-setup here, because the loop above cannot
+ distinguish between a key on the keypad and a regular key. We maybe
+ could get around this problem in another fashion: NSEvent's flags
+ include a "NSNumericPadKeyMask" bit; we could check that and modify
+ the symbol we return on the fly. However, this flag seems to exhibit
+ some weird behaviour related to the num lock key
+ */
+ keymap[QZ_KP0] = SDLK_KP0;
+ keymap[QZ_KP1] = SDLK_KP1;
+ keymap[QZ_KP2] = SDLK_KP2;
+ keymap[QZ_KP3] = SDLK_KP3;
+ keymap[QZ_KP4] = SDLK_KP4;
+ keymap[QZ_KP5] = SDLK_KP5;
+ keymap[QZ_KP6] = SDLK_KP6;
+ keymap[QZ_KP7] = SDLK_KP7;
+ keymap[QZ_KP8] = SDLK_KP8;
+ keymap[QZ_KP9] = SDLK_KP9;
+ keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
+ keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
+ keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
+ keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
+ keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
+ keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
+ keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
+}
+
+static void QZ_DoKey (_THIS, int state, NSEvent *event) {
+
+ NSString *chars = NULL;
+ unsigned int i, numChars;
+ SDL_keysym key;
+
+ /*
+ A key event can contain multiple characters,
+ or no characters at all. In most cases, it
+ will contain a single character. If it contains
+ 0 characters, we'll use 0 as the unicode. If it
+ contains multiple characters, we'll use 0 as
+ the scancode/keysym.
+ */
+ if (SDL_TranslateUNICODE && state == SDL_PRESSED) {
+ [field_edit interpretKeyEvents:[NSArray arrayWithObject:event]];
+ chars = [ event characters ];
+ numChars = [ chars length ];
+ if (numChars > 0)
+ [field_edit setString:@""];
+ } else {
+ numChars = 0;
+ }
+
+ if (numChars == 0) {
+
+ key.scancode = [ event keyCode ];
+ key.sym = keymap [ key.scancode ];
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ SDL_PrivateKeyboard (state, &key);
+ }
+ else if (numChars >= 1) {
+
+ key.scancode = [ event keyCode ];
+ key.sym = keymap [ key.scancode ];
+ key.unicode = [ chars characterAtIndex:0 ];
+ key.mod = KMOD_NONE;
+
+ SDL_PrivateKeyboard (state, &key);
+
+ for (i = 1; i < numChars; i++) {
+
+ key.scancode = 0;
+ key.sym = 0;
+ key.unicode = [ chars characterAtIndex:i];
+ key.mod = KMOD_NONE;
+
+ SDL_PrivateKeyboard (state, &key);
+ }
+ }
+
+ if (SDL_getenv ("SDL_ENABLEAPPEVENTS"))
+ [ NSApp sendEvent:event ];
+}
+
+/* This is the original behavior, before support was added for
+ * differentiating between left and right versions of the keys.
+ */
+static void QZ_DoUnsidedModifiers (_THIS, unsigned int newMods) {
+
+ const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA };
+
+ int i;
+ int bit;
+ SDL_keysym key;
+
+ key.scancode = 0;
+ key.sym = SDLK_UNKNOWN;
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ /* Iterate through the bits, testing each against the current modifiers */
+ for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
+
+ unsigned int currentMask, newMask;
+
+ currentMask = current_mods & bit;
+ newMask = newMods & bit;
+
+ if ( currentMask &&
+ currentMask != newMask ) { /* modifier up event */
+
+ key.sym = mapping[i];
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
+ if (bit == NSAlphaShiftKeyMask)
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+ else if ( newMask &&
+ currentMask != newMask ) { /* modifier down event */
+
+ key.sym = mapping[i];
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
+ if (bit == NSAlphaShiftKeyMask)
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+ }
+}
+
+/* This is a helper function for QZ_HandleModifierSide. This
+ * function reverts back to behavior before the distinction between
+ * sides was made.
+ */
+static void QZ_HandleNonDeviceModifier ( _THIS, unsigned int device_independent_mask, unsigned int newMods, unsigned int key_sym) {
+ unsigned int currentMask, newMask;
+ SDL_keysym key;
+
+ key.scancode = 0;
+ key.sym = key_sym;
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ /* Isolate just the bits we care about in the depedent bits so we can
+ * figure out what changed
+ */
+ currentMask = current_mods & device_independent_mask;
+ newMask = newMods & device_independent_mask;
+
+ if ( currentMask &&
+ currentMask != newMask ) { /* modifier up event */
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+ else if ( newMask &&
+ currentMask != newMask ) { /* modifier down event */
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ }
+}
+
+/* This is a helper function for QZ_HandleModifierSide.
+ * This function sets the actual SDL_PrivateKeyboard event.
+ */
+static void QZ_HandleModifierOneSide ( _THIS, unsigned int newMods,
+ unsigned int key_sym,
+ unsigned int sided_device_dependent_mask ) {
+
+ SDL_keysym key;
+ unsigned int current_dep_mask, new_dep_mask;
+
+ key.scancode = 0;
+ key.sym = key_sym;
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ /* Isolate just the bits we care about in the depedent bits so we can
+ * figure out what changed
+ */
+ current_dep_mask = current_mods & sided_device_dependent_mask;
+ new_dep_mask = newMods & sided_device_dependent_mask;
+
+ /* We now know that this side bit flipped. But we don't know if
+ * it went pressed to released or released to pressed, so we must
+ * find out which it is.
+ */
+ if( new_dep_mask &&
+ current_dep_mask != new_dep_mask ) {
+ /* Modifier down event */
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ }
+ else /* Modifier up event */ {
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+}
+
+/* This is a helper function for QZ_DoSidedModifiers.
+ * This function will figure out if the modifier key is the left or right side,
+ * e.g. left-shift vs right-shift.
+ */
+static void QZ_HandleModifierSide ( _THIS, int device_independent_mask,
+ unsigned int newMods,
+ unsigned int left_key_sym,
+ unsigned int right_key_sym,
+ unsigned int left_device_dependent_mask,
+ unsigned int right_device_dependent_mask ) {
+ unsigned int device_dependent_mask = 0;
+ unsigned int diff_mod = 0;
+
+ device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask;
+ /* On the basis that the device independent mask is set, but there are
+ * no device dependent flags set, we'll assume that we can't detect this
+ * keyboard and revert to the unsided behavior.
+ */
+ if ( (device_dependent_mask & newMods) == 0 ) {
+ /* Revert to the old behavior */
+ QZ_HandleNonDeviceModifier ( this, device_independent_mask, newMods, left_key_sym );
+ return;
+ }
+
+ /* XOR the previous state against the new state to see if there's a change */
+ diff_mod = (device_dependent_mask & current_mods)
+ ^ (device_dependent_mask & newMods);
+
+ if ( diff_mod ) {
+ /* A change in state was found. Isolate the left and right bits
+ * to handle them separately just in case the values can simulataneously
+ * change or if the bits don't both exist.
+ */
+ if ( left_device_dependent_mask & diff_mod ) {
+ QZ_HandleModifierOneSide ( this, newMods, left_key_sym, left_device_dependent_mask );
+ }
+ if ( right_device_dependent_mask & diff_mod ) {
+ QZ_HandleModifierOneSide ( this, newMods, right_key_sym, right_device_dependent_mask );
+ }
+ }
+}
+
+/* This is a helper function for QZ_DoSidedModifiers.
+ * This function will release a key press in the case that
+ * it is clear that the modifier has been released (i.e. one side
+ * can't still be down).
+ */
+static void QZ_ReleaseModifierSide ( _THIS,
+ unsigned int device_independent_mask,
+ unsigned int newMods,
+ unsigned int left_key_sym,
+ unsigned int right_key_sym,
+ unsigned int left_device_dependent_mask,
+ unsigned int right_device_dependent_mask ) {
+ unsigned int device_dependent_mask = 0;
+ SDL_keysym key;
+
+ key.scancode = 0;
+ key.sym = SDLK_UNKNOWN;
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ device_dependent_mask = left_device_dependent_mask | right_device_dependent_mask;
+ /* On the basis that the device independent mask is set, but there are
+ * no device dependent flags set, we'll assume that we can't detect this
+ * keyboard and revert to the unsided behavior.
+ */
+ if ( (device_dependent_mask & current_mods) == 0 ) {
+ /* In this case, we can't detect the keyboard, so use the left side
+ * to represent both, and release it.
+ */
+ key.sym = left_key_sym;
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+
+ return;
+ }
+
+
+ /*
+ * This could have been done in an if-else case because at this point,
+ * we know that all keys have been released when calling this function.
+ * But I'm being paranoid so I want to handle each separately,
+ * so I hope this doesn't cause other problems.
+ */
+ if ( left_device_dependent_mask & current_mods ) {
+ key.sym = left_key_sym;
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+ if ( right_device_dependent_mask & current_mods ) {
+ key.sym = right_key_sym;
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+}
+
+/* This is a helper function for QZ_DoSidedModifiers.
+ * This function handles the CapsLock case.
+ */
+static void QZ_HandleCapsLock (_THIS, unsigned int newMods) {
+ unsigned int currentMask, newMask;
+ SDL_keysym key;
+
+ key.scancode = 0;
+ key.sym = SDLK_CAPSLOCK;
+ key.unicode = 0;
+ key.mod = KMOD_NONE;
+
+ currentMask = current_mods & NSAlphaShiftKeyMask;
+ newMask = newMods & NSAlphaShiftKeyMask;
+
+ if ( currentMask &&
+ currentMask != newMask ) { /* modifier up event */
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+ else if ( newMask &&
+ currentMask != newMask ) { /* modifier down event */
+ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
+ SDL_PrivateKeyboard (SDL_PRESSED, &key);
+ SDL_PrivateKeyboard (SDL_RELEASED, &key);
+ }
+}
+
+/* This function will handle the modifier keys and also determine the
+ * correct side of the key.
+ */
+static void QZ_DoSidedModifiers (_THIS, unsigned int newMods) {
+ /* Set up arrays for the key syms for the left and right side. */
+ const unsigned int left_mapping[] = { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA };
+ const unsigned int right_mapping[] = { SDLK_RSHIFT, SDLK_RCTRL, SDLK_RALT, SDLK_RMETA };
+ /* Set up arrays for the device dependent masks with indices that
+ * correspond to the _mapping arrays
+ */
+ const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
+ const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
+
+ unsigned int i;
+ unsigned int bit;
+
+ /* Handle CAPSLOCK separately because it doesn't have a left/right side */
+ QZ_HandleCapsLock ( this, newMods );
+
+ /* Iterate through the bits, testing each against the current modifiers */
+ for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
+
+ unsigned int currentMask, newMask;
+
+ currentMask = current_mods & bit;
+ newMask = newMods & bit;
+
+ /* If the bit is set, we must always examine it because the left
+ * and right side keys may alternate or both may be pressed.
+ */
+ if ( newMask ) {
+ QZ_HandleModifierSide ( this, bit, newMods,
+ left_mapping[i],
+ right_mapping[i],
+ left_device_mapping[i],
+ right_device_mapping[i] );
+ }
+ /* If the state changed from pressed to unpressed, we must examine
+ * the device dependent bits to release the correct keys.
+ */
+ else if ( currentMask &&
+ currentMask != newMask ) { /* modifier up event */
+ QZ_ReleaseModifierSide ( this, bit, newMods,
+ left_mapping[i],
+ right_mapping[i],
+ left_device_mapping[i],
+ right_device_mapping[i] );
+ }
+ }
+}
+
+/* This function is called to handle the modifiers.
+ * It will try to distinguish between the left side and right side
+ * of the keyboard for those modifiers that qualify if the
+ * operating system version supports it. Otherwise, the code
+ * will not try to make the distinction.
+ */
+static void QZ_DoModifiers (_THIS, unsigned int newMods) {
+
+ if (current_mods == newMods)
+ return;
+
+ /*
+ * Starting with Panther (10.3.0), the ability to distinguish between
+ * left side and right side modifiers is available.
+ */
+ if( system_version >= 0x1030 ) {
+ QZ_DoSidedModifiers (this, newMods);
+ }
+ else {
+ QZ_DoUnsidedModifiers (this, newMods);
+ }
+
+ current_mods = newMods;
+}
+
+static void QZ_GetMouseLocation (_THIS, NSPoint *p) {
+ *p = [ NSEvent mouseLocation ]; /* global coordinates */
+ if (qz_window)
+ QZ_PrivateGlobalToLocal (this, p);
+ QZ_PrivateCocoaToSDL (this, p);
+}
+
+void QZ_DoActivate (_THIS) {
+
+ SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0));
+
+ QZ_UpdateCursor(this);
+
+ /* Regrab input, only if it was previously grabbed */
+ if ( current_grab_mode == SDL_GRAB_ON ) {
+
+ /* Restore cursor location if input was grabbed */
+ QZ_PrivateWarpCursor (this, cursor_loc.x, cursor_loc.y);
+ QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
+ }
+ else {
+ /* Update SDL's mouse location */
+ NSPoint p;
+ QZ_GetMouseLocation (this, &p);
+ SDL_PrivateMouseMotion (0, 0, p.x, p.y);
+ }
+
+ QZ_UpdateCursor(this);
+}
+
+void QZ_DoDeactivate (_THIS) {
+
+ SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS | SDL_APPMOUSEFOCUS);
+
+ /* Get the current cursor location, for restore on activate */
+ QZ_GetMouseLocation (this, &cursor_loc);
+
+ /* Reassociate mouse and cursor */
+ CGAssociateMouseAndMouseCursorPosition (1);
+
+ QZ_UpdateCursor(this);
+}
+
+void QZ_SleepNotificationHandler (void * refcon,
+ io_service_t service,
+ natural_t messageType,
+ void * messageArgument )
+{
+ SDL_VideoDevice *this = (SDL_VideoDevice*)refcon;
+
+ switch(messageType)
+ {
+ case kIOMessageSystemWillSleep:
+ IOAllowPowerChange(power_connection, (long) messageArgument);
+ break;
+ case kIOMessageCanSystemSleep:
+ IOAllowPowerChange(power_connection, (long) messageArgument);
+ break;
+ case kIOMessageSystemHasPoweredOn:
+ /* awake */
+ SDL_PrivateExpose();
+ break;
+ }
+}
+
+void QZ_RegisterForSleepNotifications (_THIS)
+{
+ CFRunLoopSourceRef rls;
+ IONotificationPortRef thePortRef;
+ io_object_t notifier;
+
+ power_connection = IORegisterForSystemPower (this, &thePortRef, QZ_SleepNotificationHandler, &notifier);
+
+ if (power_connection == 0)
+ NSLog(@"SDL: QZ_SleepNotificationHandler() IORegisterForSystemPower failed.");
+
+ rls = IONotificationPortGetRunLoopSource (thePortRef);
+ CFRunLoopAddSource (CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease (rls);
+}
+
+
+/* Try to map Quartz mouse buttons to SDL's lingo... */
+static int QZ_OtherMouseButtonToSDL(int button)
+{
+ switch (button)
+ {
+ case 0:
+ return(SDL_BUTTON_LEFT); /* 1 */
+ case 1:
+ return(SDL_BUTTON_RIGHT); /* 3 */
+ case 2:
+ return(SDL_BUTTON_MIDDLE); /* 2 */
+ }
+
+ /* >= 3: skip 4 & 5, since those are the SDL mousewheel buttons. */
+ return(button + 3);
+}
+
+
+void QZ_PumpEvents (_THIS)
+{
+ int32_t dx, dy;
+
+ NSDate *distantPast;
+ NSEvent *event;
+ NSRect winRect;
+ NSAutoreleasePool *pool;
+
+ if (!SDL_VideoSurface)
+ return; /* don't do anything if there's no screen surface. */
+
+ /* Update activity every five seconds to prevent screensaver. --ryan. */
+ if (!allow_screensaver) {
+ static Uint32 screensaverTicks;
+ Uint32 nowTicks = SDL_GetTicks();
+ if ((nowTicks - screensaverTicks) > 5000)
+ {
+ UpdateSystemActivity(UsrActivity);
+ screensaverTicks = nowTicks;
+ }
+ }
+
+ pool = [ [ NSAutoreleasePool alloc ] init ];
+ distantPast = [ NSDate distantPast ];
+
+ winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
+
+ /* while grabbed, accumulate all mouse moved events into one SDL mouse event */
+ dx = 0;
+ dy = 0;
+
+ do {
+
+ /* Poll for an event. This will not block */
+ event = [ NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:distantPast
+ inMode: NSDefaultRunLoopMode dequeue:YES ];
+ if (event != nil) {
+
+ int button;
+ unsigned int type;
+ BOOL isInGameWin;
+
+ #define DO_MOUSE_DOWN(button) do { \
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { \
+ SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
+ expect_mouse_up |= 1<<button; \
+ } \
+ [ NSApp sendEvent:event ]; \
+ } while(0)
+
+ #define DO_MOUSE_UP(button) do { \
+ if ( expect_mouse_up & (1<<button) ) { \
+ SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
+ expect_mouse_up &= ~(1<<button); \
+ } \
+ [ NSApp sendEvent:event ]; \
+ } while(0)
+
+ type = [ event type ];
+ isInGameWin = QZ_IsMouseInWindow (this);
+
+ QZ_DoModifiers(this, [ event modifierFlags ] );
+
+ switch (type) {
+ case NSLeftMouseDown:
+ if ( SDL_getenv("SDL_HAS3BUTTONMOUSE") ) {
+ DO_MOUSE_DOWN (SDL_BUTTON_LEFT);
+ } else {
+ if ( NSCommandKeyMask & current_mods ) {
+ last_virtual_button = SDL_BUTTON_RIGHT;
+ DO_MOUSE_DOWN (SDL_BUTTON_RIGHT);
+ }
+ else if ( NSAlternateKeyMask & current_mods ) {
+ last_virtual_button = SDL_BUTTON_MIDDLE;
+ DO_MOUSE_DOWN (SDL_BUTTON_MIDDLE);
+ }
+ else {
+ DO_MOUSE_DOWN (SDL_BUTTON_LEFT);
+ }
+ }
+ break;
+
+ case NSLeftMouseUp:
+ if ( last_virtual_button != 0 ) {
+ DO_MOUSE_UP (last_virtual_button);
+ last_virtual_button = 0;
+ }
+ else {
+ DO_MOUSE_UP (SDL_BUTTON_LEFT);
+ }
+ break;
+
+ case NSOtherMouseDown:
+ case NSRightMouseDown:
+ button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]);
+ DO_MOUSE_DOWN (button);
+ break;
+
+ case NSOtherMouseUp:
+ case NSRightMouseUp:
+ button = QZ_OtherMouseButtonToSDL([ event buttonNumber ]);
+ DO_MOUSE_UP (button);
+ break;
+
+ case NSSystemDefined:
+ /*
+ Future: up to 32 "mouse" buttons can be handled.
+ if ([event subtype] == 7) {
+ unsigned int buttons;
+ buttons = [ event data2 ];
+ */
+ break;
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged: /* usually middle mouse dragged */
+ case NSMouseMoved:
+ if ( grab_state == QZ_INVISIBLE_GRAB ) {
+
+ /*
+ If input is grabbed+hidden, the cursor doesn't move,
+ so we have to call the lowlevel window server
+ function. This is less accurate but works OK.
+ */
+ int32_t dx1, dy1;
+ CGGetLastMouseDelta (&dx1, &dy1);
+ dx += dx1;
+ dy += dy1;
+ }
+ else {
+
+ /*
+ Get the absolute mouse location. This is not the
+ mouse location after the currently processed event,
+ but the *current* mouse location, i.e. after all
+ pending events. This means that if there are
+ multiple mouse moved events in the queue, we make
+ multiple identical calls to SDL_PrivateMouseMotion(),
+ but that's no problem since the latter only
+ generates SDL events for nonzero movements. In my
+ experience on PBG4/10.4.8, this rarely happens anyway.
+ */
+ NSPoint p;
+ QZ_GetMouseLocation (this, &p);
+ SDL_PrivateMouseMotion (0, 0, p.x, p.y);
+ }
+
+ /*
+ Handle grab input+cursor visible by warping the cursor back
+ into the game window. This still generates a mouse moved event,
+ but not as a result of the warp (so it's in the right direction).
+ */
+ if ( grab_state == QZ_VISIBLE_GRAB && !isInGameWin ) {
+
+ NSPoint p;
+ QZ_GetMouseLocation (this, &p);
+
+ if ( p.x < 0.0 )
+ p.x = 0.0;
+
+ if ( p.y < 0.0 )
+ p.y = 0.0;
+
+ if ( p.x >= winRect.size.width )
+ p.x = winRect.size.width-1;
+
+ if ( p.y >= winRect.size.height )
+ p.y = winRect.size.height-1;
+
+ QZ_PrivateWarpCursor (this, p.x, p.y);
+ }
+ else
+ if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+
+ SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS);
+
+ if (grab_state == QZ_INVISIBLE_GRAB)
+ /*The cursor has left the window even though it is
+ disassociated from the mouse (and therefore
+ shouldn't move): this can happen with Wacom
+ tablets, and it effectively breaks the grab, since
+ mouse down events now go to background
+ applications. The only possibility to avoid this
+ seems to be talking to the tablet driver
+ (AppleEvents) to constrain its mapped area to the
+ window, which may not be worth the effort. For
+ now, handle the condition more gracefully than
+ before by reassociating cursor and mouse until the
+ cursor enters the window again, making it obvious
+ to the user that the grab is broken.*/
+ CGAssociateMouseAndMouseCursorPosition (1);
+
+ QZ_UpdateCursor(this);
+ }
+ else
+ if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) {
+
+ SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS);
+
+ QZ_UpdateCursor(this);
+
+ if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/
+ QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
+ CGAssociateMouseAndMouseCursorPosition (0);
+ }
+ }
+ break;
+ case NSScrollWheel:
+ if ( isInGameWin ) {
+ float dy, dx;
+ Uint8 button;
+ dy = [ event deltaY ];
+ dx = [ event deltaX ];
+ if ( dy > 0.0 ) /* Scroll up */
+ button = SDL_BUTTON_WHEELUP;
+ else if ( dy < 0.0 ) /* Scroll down */
+ button = SDL_BUTTON_WHEELDOWN;
+ else
+ break; /* Horizontal scroll */
+ /* For now, wheel is sent as a quick down+up */
+ SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);
+ SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);
+ }
+ break;
+ case NSKeyUp:
+ QZ_DoKey (this, SDL_RELEASED, event);
+ break;
+ case NSKeyDown:
+ QZ_DoKey (this, SDL_PRESSED, event);
+ break;
+ case NSFlagsChanged:
+ break;
+ case NSAppKitDefined:
+ [ NSApp sendEvent:event ];
+ if ([ event subtype ] == NSApplicationActivatedEventType && (mode_flags & SDL_FULLSCREEN)) {
+ /* the default handling of this event seems to reset any cursor set by [NSCursor set] (used by SDL_SetCursor() in fullscreen mode) to the default system arrow cursor */
+ SDL_Cursor *sdlc = SDL_GetCursor();
+ if (sdlc != NULL && sdlc->wm_cursor != NULL) {
+ [ sdlc->wm_cursor->nscursor set ];
+ }
+ }
+ break;
+ /* case NSApplicationDefined: break; */
+ /* case NSPeriodic: break; */
+ /* case NSCursorUpdate: break; */
+ default:
+ [ NSApp sendEvent:event ];
+ }
+ }
+ } while (event != nil);
+
+ /* handle accumulated mouse moved events */
+ if (dx != 0 || dy != 0)
+ SDL_PrivateMouseMotion (0, 1, dx, dy);
+
+ [ pool release ];
+}
+
+void QZ_UpdateMouse (_THIS)
+{
+ NSPoint p;
+ QZ_GetMouseLocation (this, &p);
+ SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS);
+ SDL_PrivateMouseMotion (0, 0, p.x, p.y);
+}
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzGL.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzGL.m
new file mode 100644
index 0000000..d38dceb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzGL.m
@@ -0,0 +1,292 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QuartzVideo.h"
+
+/*
+ * GL_ARB_Multisample is supposed to be available in 10.1, according to Apple:
+ *
+ * http://developer.apple.com/graphicsimaging/opengl/extensions.html#GL_ARB_multisample
+ *
+ * ...but it isn't in the system headers, according to Sam:
+ *
+ * http://lists.libsdl.org/pipermail/sdl-libsdl.org/2003-December/039794.html
+ *
+ * These are normally enums and not #defines in the system headers.
+ *
+ * --ryan.
+ */
+#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1020)
+#define NSOpenGLPFASampleBuffers ((NSOpenGLPixelFormatAttribute) 55)
+#define NSOpenGLPFASamples ((NSOpenGLPixelFormatAttribute) 56)
+#endif
+
+#ifdef __powerpc__ /* we lost this in 10.6, which has no PPC support. */
+@implementation NSOpenGLContext (CGLContextAccess)
+- (CGLContextObj) cglContext;
+{
+ return _contextAuxiliary;
+}
+@end
+CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx)
+{
+ return [nsctx cglContext];
+}
+#else
+CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx)
+{
+ return (CGLContextObj) [nsctx CGLContextObj];
+}
+#endif
+
+
+/* OpenGL helper functions (used internally) */
+
+int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
+
+ NSOpenGLPixelFormatAttribute attr[32];
+ NSOpenGLPixelFormat *fmt;
+ int i = 0;
+ int colorBits = bpp;
+
+ /* if a GL library hasn't been loaded at this point, load the default. */
+ if (!this->gl_config.driver_loaded) {
+ if (QZ_GL_LoadLibrary(this, NULL) == -1)
+ return 0;
+ }
+
+ if ( flags & SDL_FULLSCREEN ) {
+
+ attr[i++] = NSOpenGLPFAFullScreen;
+ }
+ /* In windowed mode, the OpenGL pixel depth must match device pixel depth */
+ else if ( colorBits != device_bpp ) {
+
+ colorBits = device_bpp;
+ }
+
+ attr[i++] = NSOpenGLPFAColorSize;
+ attr[i++] = colorBits;
+
+ attr[i++] = NSOpenGLPFADepthSize;
+ attr[i++] = this->gl_config.depth_size;
+
+ if ( this->gl_config.double_buffer ) {
+ attr[i++] = NSOpenGLPFADoubleBuffer;
+ }
+
+ if ( this->gl_config.stereo ) {
+ attr[i++] = NSOpenGLPFAStereo;
+ }
+
+ if ( this->gl_config.stencil_size != 0 ) {
+ attr[i++] = NSOpenGLPFAStencilSize;
+ attr[i++] = this->gl_config.stencil_size;
+ }
+
+ if ( (this->gl_config.accum_red_size +
+ this->gl_config.accum_green_size +
+ this->gl_config.accum_blue_size +
+ this->gl_config.accum_alpha_size) > 0 ) {
+ attr[i++] = NSOpenGLPFAAccumSize;
+ attr[i++] = this->gl_config.accum_red_size + this->gl_config.accum_green_size + this->gl_config.accum_blue_size + this->gl_config.accum_alpha_size;
+ }
+
+ if ( this->gl_config.multisamplebuffers != 0 ) {
+ attr[i++] = NSOpenGLPFASampleBuffers;
+ attr[i++] = this->gl_config.multisamplebuffers;
+ }
+
+ if ( this->gl_config.multisamplesamples != 0 ) {
+ attr[i++] = NSOpenGLPFASamples;
+ attr[i++] = this->gl_config.multisamplesamples;
+ attr[i++] = NSOpenGLPFANoRecovery;
+ }
+
+ if ( this->gl_config.accelerated > 0 ) {
+ attr[i++] = NSOpenGLPFAAccelerated;
+ }
+
+ attr[i++] = NSOpenGLPFAScreenMask;
+ attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);
+ attr[i] = 0;
+
+ fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];
+ if (fmt == nil) {
+ SDL_SetError ("Failed creating OpenGL pixel format");
+ return 0;
+ }
+
+ gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt
+ shareContext:nil];
+
+ [ fmt release ];
+
+ if (gl_context == nil) {
+ SDL_SetError ("Failed creating OpenGL context");
+ return 0;
+ }
+
+ /* Synchronize QZ_GL_SwapBuffers() to vertical retrace.
+ * (Apple's documentation is not completely clear about what this setting
+ * exactly does, IMHO - for a detailed explanation see
+ * http://lists.apple.com/archives/mac-opengl/2006/Jan/msg00080.html )
+ */
+ if ( this->gl_config.swap_control >= 0 ) {
+ GLint value;
+ value = this->gl_config.swap_control;
+ [ gl_context setValues: &value forParameter: NSOpenGLCPSwapInterval ];
+ }
+
+ /*
+ * Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
+ * "You are blowing a couple of the internal OpenGL function caches. This
+ * appears to be happening in the VAO case. You can tell OpenGL to up
+ * the cache size by issuing the following calls right after you create
+ * the OpenGL context. The default cache size is 16." --ryan.
+ */
+
+ #ifndef GLI_ARRAY_FUNC_CACHE_MAX
+ #define GLI_ARRAY_FUNC_CACHE_MAX 284
+ #endif
+
+ #ifndef GLI_SUBMIT_FUNC_CACHE_MAX
+ #define GLI_SUBMIT_FUNC_CACHE_MAX 280
+ #endif
+
+ {
+ GLint cache_max = 64;
+ CGLContextObj ctx = QZ_GetCGLContextObj(gl_context);
+ CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
+ CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
+ }
+
+ /* End Wisdom from Apple Engineer section. --ryan. */
+
+ return 1;
+}
+
+void QZ_TearDownOpenGL (_THIS) {
+
+ [ NSOpenGLContext clearCurrentContext ];
+ [ gl_context clearDrawable ];
+ [ gl_context release ];
+}
+
+
+/* SDL OpenGL functions */
+static const char *DEFAULT_OPENGL_LIB_NAME =
+ "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
+
+int QZ_GL_LoadLibrary (_THIS, const char *location) {
+ if ( gl_context != NULL ) {
+ SDL_SetError("OpenGL context already created");
+ return -1;
+ }
+
+ if (opengl_library != NULL)
+ SDL_UnloadObject(opengl_library);
+
+ if (location == NULL)
+ location = DEFAULT_OPENGL_LIB_NAME;
+
+ opengl_library = SDL_LoadObject(location);
+ if (opengl_library != NULL) {
+ this->gl_config.driver_loaded = 1;
+ return 0;
+ }
+
+ this->gl_config.driver_loaded = 0;
+ return -1;
+}
+
+void* QZ_GL_GetProcAddress (_THIS, const char *proc) {
+ return SDL_LoadFunction(opengl_library, proc);
+}
+
+int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) {
+
+ GLenum attr = 0;
+
+ QZ_GL_MakeCurrent (this);
+
+ switch (attrib) {
+ case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
+ case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
+ case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
+ case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
+ case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
+ case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
+ case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
+ case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
+ case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
+ case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
+ case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
+ case SDL_GL_STEREO: attr = GL_STEREO; break;
+ case SDL_GL_MULTISAMPLEBUFFERS: attr = GL_SAMPLE_BUFFERS_ARB; break;
+ case SDL_GL_MULTISAMPLESAMPLES: attr = GL_SAMPLES_ARB; break;
+ case SDL_GL_BUFFER_SIZE:
+ {
+ GLint bits = 0;
+ GLint component;
+
+ /* there doesn't seem to be a single flag in OpenGL for this! */
+ glGetIntegerv (GL_RED_BITS, &component); bits += component;
+ glGetIntegerv (GL_GREEN_BITS,&component); bits += component;
+ glGetIntegerv (GL_BLUE_BITS, &component); bits += component;
+ glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;
+
+ *value = bits;
+ return 0;
+ }
+ case SDL_GL_ACCELERATED_VISUAL:
+ {
+ GLint val;
+ /* FIXME: How do we get this information here?
+ [fmt getValues: &val forAttribute: NSOpenGLPFAAccelerated attr forVirtualScreen: 0];
+ */
+ val = (this->gl_config.accelerated != 0);;
+ *value = val;
+ return 0;
+ }
+ case SDL_GL_SWAP_CONTROL:
+ {
+ GLint val;
+ [ gl_context getValues: &val forParameter: NSOpenGLCPSwapInterval ];
+ *value = val;
+ return 0;
+ }
+ }
+
+ glGetIntegerv (attr, (GLint *)value);
+ return 0;
+}
+
+int QZ_GL_MakeCurrent (_THIS) {
+ [ gl_context makeCurrentContext ];
+ return 0;
+}
+
+void QZ_GL_SwapBuffers (_THIS) {
+ [ gl_context flushBuffer ];
+}
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzKeys.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzKeys.h
new file mode 100644
index 0000000..82b7859
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzKeys.h
@@ -0,0 +1,146 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* These are the Macintosh key scancode constants -- from Inside Macintosh */
+
+#define QZ_ESCAPE 0x35
+#define QZ_F1 0x7A
+#define QZ_F2 0x78
+#define QZ_F3 0x63
+#define QZ_F4 0x76
+#define QZ_F5 0x60
+#define QZ_F6 0x61
+#define QZ_F7 0x62
+#define QZ_F8 0x64
+#define QZ_F9 0x65
+#define QZ_F10 0x6D
+#define QZ_F11 0x67
+#define QZ_F12 0x6F
+#define QZ_F13 0x69
+#define QZ_F14 0x6B
+#define QZ_F15 0x71
+/*
+#define QZ_PRINT 0x69
+#define QZ_SCROLLOCK 0x6B
+#define QZ_PAUSE 0x71
+*/
+#define QZ_POWER 0x7F
+#define QZ_BACKQUOTE 0x32
+#define QZ_1 0x12
+#define QZ_2 0x13
+#define QZ_3 0x14
+#define QZ_4 0x15
+#define QZ_5 0x17
+#define QZ_6 0x16
+#define QZ_7 0x1A
+#define QZ_8 0x1C
+#define QZ_9 0x19
+#define QZ_0 0x1D
+#define QZ_MINUS 0x1B
+#define QZ_EQUALS 0x18
+#define QZ_BACKSPACE 0x33
+#define QZ_INSERT 0x72
+#define QZ_HOME 0x73
+#define QZ_PAGEUP 0x74
+#define QZ_NUMLOCK 0x47
+#define QZ_KP_EQUALS 0x51
+#define QZ_KP_DIVIDE 0x4B
+#define QZ_KP_MULTIPLY 0x43
+#define QZ_TAB 0x30
+#define QZ_q 0x0C
+#define QZ_w 0x0D
+#define QZ_e 0x0E
+#define QZ_r 0x0F
+#define QZ_t 0x11
+#define QZ_y 0x10
+#define QZ_u 0x20
+#define QZ_i 0x22
+#define QZ_o 0x1F
+#define QZ_p 0x23
+#define QZ_LEFTBRACKET 0x21
+#define QZ_RIGHTBRACKET 0x1E
+#define QZ_BACKSLASH 0x2A
+#define QZ_DELETE 0x75
+#define QZ_END 0x77
+#define QZ_PAGEDOWN 0x79
+#define QZ_KP7 0x59
+#define QZ_KP8 0x5B
+#define QZ_KP9 0x5C
+#define QZ_KP_MINUS 0x4E
+#define QZ_CAPSLOCK 0x39
+#define QZ_a 0x00
+#define QZ_s 0x01
+#define QZ_d 0x02
+#define QZ_f 0x03
+#define QZ_g 0x05
+#define QZ_h 0x04
+#define QZ_j 0x26
+#define QZ_k 0x28
+#define QZ_l 0x25
+#define QZ_SEMICOLON 0x29
+#define QZ_QUOTE 0x27
+#define QZ_RETURN 0x24
+#define QZ_KP4 0x56
+#define QZ_KP5 0x57
+#define QZ_KP6 0x58
+#define QZ_KP_PLUS 0x45
+#define QZ_LSHIFT 0x38
+#define QZ_z 0x06
+#define QZ_x 0x07
+#define QZ_c 0x08
+#define QZ_v 0x09
+#define QZ_b 0x0B
+#define QZ_n 0x2D
+#define QZ_m 0x2E
+#define QZ_COMMA 0x2B
+#define QZ_PERIOD 0x2F
+#define QZ_SLASH 0x2C
+#if 1 /* Panther now defines right side keys */
+#define QZ_RSHIFT 0x3C
+#endif
+#define QZ_UP 0x7E
+#define QZ_KP1 0x53
+#define QZ_KP2 0x54
+#define QZ_KP3 0x55
+#define QZ_KP_ENTER 0x4C
+#define QZ_LCTRL 0x3B
+#define QZ_LALT 0x3A
+#define QZ_LMETA 0x37
+#define QZ_SPACE 0x31
+#if 1 /* Panther now defines right side keys */
+#define QZ_RMETA 0x36
+#define QZ_RALT 0x3D
+#define QZ_RCTRL 0x3E
+#endif
+#define QZ_LEFT 0x7B
+#define QZ_DOWN 0x7D
+#define QZ_RIGHT 0x7C
+#define QZ_KP0 0x52
+#define QZ_KP_PERIOD 0x41
+
+/* Wierd, these keys are on my iBook under Mac OS X */
+#define QZ_IBOOK_ENTER 0x34
+#define QZ_IBOOK_LEFT 0x3B
+#define QZ_IBOOK_RIGHT 0x3C
+#define QZ_IBOOK_DOWN 0x3D
+#define QZ_IBOOK_UP 0x3E
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h
new file mode 100644
index 0000000..d00e496
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h
@@ -0,0 +1,235 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ @file SDL_QuartzVideo.h
+ @author Darrell Walisser, Max Horn, et al.
+
+ @abstract SDL video driver for Mac OS X.
+
+ @discussion
+
+ TODO
+ - Hardware Cursor support with NSCursor instead of Carbon
+ - Keyboard repeat/mouse speed adjust (if needed)
+ - Multiple monitor support (currently only main display)
+ - Accelerated blitting support
+ - Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
+ - Find out what events should be sent/ignored if window is minimized
+ - Find a way to deal with external resolution/depth switch while app is running
+ - Check accuracy of QZ_SetGamma()
+ Problems:
+ - OGL not working in full screen with software renderer
+ - SetColors sets palette correctly but clears framebuffer
+ - Crash in CG after several mode switches (I think this has been fixed)
+ - Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
+ - Cursor in 8 bit modes is screwy (might just be Radeon PCI bug) (update: not just Radeon)
+ - Warping cursor delays mouse events for a fraction of a second,
+ there is a hack around this that helps a bit
+*/
+
+/* Needs to be first, so QuickTime.h doesn't include glext.h (10.4) */
+#include "SDL_opengl.h"
+
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
+#include <OpenGL/OpenGL.h> /* For CGL functions and types */
+#include <IOKit/IOKitLib.h> /* For powersave handling */
+#include <pthread.h>
+
+#include "SDL_thread.h"
+#include "SDL_video.h"
+#include "SDL_error.h"
+#include "SDL_timer.h"
+#include "SDL_loadso.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+
+#ifdef __powerpc__
+/*
+ This is a workaround to directly access NSOpenGLContext's CGL context
+ We need this to check for errors NSOpenGLContext doesn't support
+ Please note this is only used on PowerPC (Intel Macs are guaranteed to
+ have a better API for this, since it showed up in Mac OS X 10.3).
+*/
+@interface NSOpenGLContext (CGLContextAccess)
+- (CGLContextObj) cglContext;
+@end
+#endif
+
+/* use this to get the CGLContext; it handles Cocoa interface changes. */
+CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx);
+
+
+/* Main driver structure to store required state information */
+typedef struct SDL_PrivateVideoData {
+ BOOL use_new_mode_apis; /* 1 == >= 10.6 APIs available */
+ BOOL allow_screensaver; /* 0 == disable screensaver */
+ CGDirectDisplayID display; /* 0 == main display (only support single display) */
+ const void *mode; /* current mode of the display */
+ const void *save_mode; /* original mode of the display */
+ CGDirectPaletteRef palette; /* palette of an 8-bit display */
+ NSOpenGLContext *gl_context; /* OpenGL rendering context */
+ NSGraphicsContext *nsgfx_context; /* Cocoa graphics context */
+ Uint32 width, height, bpp; /* frequently used data about the display */
+ Uint32 flags; /* flags for current mode, for teardown purposes */
+ Uint32 video_set; /* boolean; indicates if video was set correctly */
+ Uint32 warp_flag; /* boolean; notify to event loop that a warp just occured */
+ Uint32 warp_ticks; /* timestamp when the warp occured */
+ NSWindow *window; /* Cocoa window to implement the SDL window */
+ NSView *view; /* the window's view; draw 2D and OpenGL into this view */
+ CGContextRef cg_context; /* CoreGraphics rendering context */
+ SDL_Surface *resize_icon; /* icon for the resize badge, we have to draw it by hand */
+ SDL_GrabMode current_grab_mode; /* default value is SDL_GRAB_OFF */
+ SDL_Rect **client_mode_list; /* resolution list to pass back to client */
+ SDLKey keymap[256]; /* Mac OS X to SDL key mapping */
+ Uint32 current_mods; /* current keyboard modifiers, to track modifier state */
+ NSText *field_edit; /* a field editor for keyboard composition processing */
+ Uint32 last_virtual_button;/* last virtual mouse button pressed */
+ io_connect_t power_connection; /* used with IOKit to detect wake from sleep */
+ Uint8 expect_mouse_up; /* used to determine when to send mouse up events */
+ Uint8 grab_state; /* used to manage grab behavior */
+ NSPoint cursor_loc; /* saved cursor coords, for activate/deactivate when grabbed */
+ BOOL cursor_should_be_visible; /* tells if cursor is supposed to be visible (SDL_ShowCursor) */
+ BOOL cursor_visible; /* tells if cursor is *actually* visible or not */
+ Uint8* sw_buffers[2]; /* pointers to the two software buffers for double-buffer emulation */
+ SDL_Thread *thread; /* thread for async updates to the screen */
+ SDL_sem *sem1, *sem2; /* synchronization for async screen updates */
+ Uint8 *current_buffer; /* the buffer being copied to the screen */
+ BOOL quit_thread; /* used to quit the async blitting thread */
+ SInt32 system_version; /* used to dis-/enable workarounds depending on the system version */
+
+ void *opengl_library; /* dynamically loaded OpenGL library. */
+} SDL_PrivateVideoData;
+
+#define _THIS SDL_VideoDevice *this
+#define display_id (this->hidden->display)
+#define mode (this->hidden->mode)
+#define save_mode (this->hidden->save_mode)
+#define use_new_mode_apis (this->hidden->use_new_mode_apis)
+#define allow_screensaver (this->hidden->allow_screensaver)
+#define palette (this->hidden->palette)
+#define gl_context (this->hidden->gl_context)
+#define nsgfx_context (this->hidden->nsgfx_context)
+#define device_width (this->hidden->width)
+#define device_height (this->hidden->height)
+#define device_bpp (this->hidden->bpp)
+#define mode_flags (this->hidden->flags)
+#define qz_window (this->hidden->window)
+#define window_view (this->hidden->view)
+#define cg_context (this->hidden->cg_context)
+#define video_set (this->hidden->video_set)
+#define warp_ticks (this->hidden->warp_ticks)
+#define warp_flag (this->hidden->warp_flag)
+#define resize_icon (this->hidden->resize_icon)
+#define current_grab_mode (this->hidden->current_grab_mode)
+#define client_mode_list (this->hidden->client_mode_list)
+#define keymap (this->hidden->keymap)
+#define current_mods (this->hidden->current_mods)
+#define field_edit (this->hidden->field_edit)
+#define last_virtual_button (this->hidden->last_virtual_button)
+#define power_connection (this->hidden->power_connection)
+#define expect_mouse_up (this->hidden->expect_mouse_up)
+#define grab_state (this->hidden->grab_state)
+#define cursor_loc (this->hidden->cursor_loc)
+#define cursor_should_be_visible (this->hidden->cursor_should_be_visible)
+#define cursor_visible (this->hidden->cursor_visible)
+#define sw_buffers (this->hidden->sw_buffers)
+#define sw_contexts (this->hidden->sw_contexts)
+#define thread (this->hidden->thread)
+#define sem1 (this->hidden->sem1)
+#define sem2 (this->hidden->sem2)
+#define current_buffer (this->hidden->current_buffer)
+#define quit_thread (this->hidden->quit_thread)
+#define system_version (this->hidden->system_version)
+#define opengl_library (this->hidden->opengl_library)
+
+/* grab states - the input is in one of these states */
+enum {
+ QZ_UNGRABBED = 0,
+ QZ_VISIBLE_GRAB,
+ QZ_INVISIBLE_GRAB
+};
+
+/* grab actions - these can change the grabbed state */
+enum {
+ QZ_ENABLE_GRAB = 0,
+ QZ_DISABLE_GRAB,
+ QZ_HIDECURSOR,
+ QZ_SHOWCURSOR
+};
+
+/* Gamma Functions */
+int QZ_SetGamma (_THIS, float red, float green, float blue);
+int QZ_GetGamma (_THIS, float *red, float *green, float *blue);
+int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
+int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
+
+/* OpenGL functions */
+int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
+void QZ_TearDownOpenGL (_THIS);
+void* QZ_GL_GetProcAddress (_THIS, const char *proc);
+int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value);
+int QZ_GL_MakeCurrent (_THIS);
+void QZ_GL_SwapBuffers (_THIS);
+int QZ_GL_LoadLibrary (_THIS, const char *location);
+
+/* Cursor and Mouse functions */
+void QZ_FreeWMCursor (_THIS, WMcursor *cursor);
+WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
+ int w, int h, int hot_x, int hot_y);
+int QZ_ShowWMCursor (_THIS, WMcursor *cursor);
+void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y);
+void QZ_MoveWMCursor (_THIS, int x, int y);
+void QZ_CheckMouseMode (_THIS);
+void QZ_UpdateMouse (_THIS);
+
+/* Event functions */
+void QZ_InitOSKeymap (_THIS);
+void QZ_PumpEvents (_THIS);
+
+/* Window Manager functions */
+void QZ_SetCaption (_THIS, const char *title, const char *icon);
+void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask);
+int QZ_IconifyWindow (_THIS);
+void QZ_SetWindowPos (_THIS, int x, int y);
+void QZ_GetWindowPos (_THIS, int *px, int *py);
+int QZ_IsWindowVisible (_THIS, int recenter);
+int QZ_GetMonitorDPI (_THIS, int *xDpi, int *yDpi);
+int QZ_GetMonitorRect (_THIS, SDL_Rect *rect);
+
+SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
+/*int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
+
+/* Private functions (used internally) */
+void QZ_PrivateWarpCursor (_THIS, int x, int y);
+void QZ_ChangeGrabState (_THIS, int action);
+void QZ_RegisterForSleepNotifications (_THIS);
+void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
+void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
+BOOL QZ_IsMouseInWindow (_THIS);
+void QZ_DoActivate (_THIS);
+void QZ_DoDeactivate (_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m
new file mode 100644
index 0000000..bb20172
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m
@@ -0,0 +1,1695 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWindow.h"
+#include "SDL_QuartzWM.h"
+
+/* These APIs aren't just deprecated; they're gone from the headers in the
+ 10.7 SDK. If we're using a >= 10.7 SDK, but targeting < 10.7, then we
+ force these function declarations. */
+#if ((MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070))
+CG_EXTERN void *CGDisplayBaseAddress(CGDirectDisplayID display)
+ CG_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6,
+ __IPHONE_NA, __IPHONE_NA);
+CG_EXTERN size_t CGDisplayBytesPerRow(CGDirectDisplayID display)
+ CG_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_6,
+ __IPHONE_NA, __IPHONE_NA);
+#endif
+
+
+static inline BOOL IS_LION_OR_LATER(_THIS)
+{
+ return (system_version >= 0x1070);
+}
+
+static inline BOOL IS_SNOW_LEOPARD_OR_LATER(_THIS)
+{
+ return (system_version >= 0x1060);
+}
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) && !defined(__LP64__) /* Fixed in Snow Leopard */
+/*
+ Add methods to get at private members of NSScreen.
+ Since there is a bug in Apple's screen switching code
+ that does not update this variable when switching
+ to fullscreen, we'll set it manually (but only for the
+ main screen).
+*/
+@interface NSScreen (NSScreenAccess)
+- (void) setFrame:(NSRect)frame;
+@end
+
+@implementation NSScreen (NSScreenAccess)
+- (void) setFrame:(NSRect)frame;
+{
+ _frame = frame;
+}
+@end
+static inline void QZ_SetFrame(_THIS, NSScreen *nsscreen, NSRect frame)
+{
+ if (!IS_SNOW_LEOPARD_OR_LATER(this)) {
+ [nsscreen setFrame:frame];
+ }
+}
+#else
+static inline void QZ_SetFrame(_THIS, NSScreen *nsscreen, NSRect frame)
+{
+}
+#endif
+
+@interface SDLTranslatorResponder : NSTextView
+{
+}
+- (void) doCommandBySelector:(SEL)myselector;
+@end
+
+@implementation SDLTranslatorResponder
+- (void) doCommandBySelector:(SEL) myselector {}
+@end
+
+/* absent in 10.3.9. */
+CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
+
+/* Bootstrap functions */
+static int QZ_Available ();
+static SDL_VideoDevice* QZ_CreateDevice (int device_index);
+static void QZ_DeleteDevice (SDL_VideoDevice *device);
+
+/* Initialization, Query, Setup, and Redrawing functions */
+static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format);
+
+static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format,
+ Uint32 flags);
+static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop, BOOL save_gl);
+
+static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current,
+ int width, int height, int bpp,
+ Uint32 flags);
+static int QZ_ToggleFullScreen (_THIS, int on);
+static int QZ_SetColors (_THIS, int first_color,
+ int num_colors, SDL_Color *colors);
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+static int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface);
+static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface);
+static int QZ_ThreadFlip (_THIS);
+static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface);
+static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects);
+static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects);
+#endif
+
+static void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
+static void QZ_VideoQuit (_THIS);
+
+static int QZ_LockHWSurface(_THIS, SDL_Surface *surface);
+static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static int QZ_AllocHWSurface(_THIS, SDL_Surface *surface);
+static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface);
+
+/* Bootstrap binding, enables entry point into the driver */
+VideoBootStrap QZ_bootstrap = {
+ "Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
+};
+
+/* Disable compiler warnings we can't avoid. */
+#if (defined(__GNUC__) && (__GNUC__ >= 4))
+# if (MAC_OS_X_VERSION_MAX_ALLOWED <= 1070)
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+# endif
+#endif
+
+static void QZ_ReleaseDisplayMode(_THIS, const void *moderef)
+{
+ /* we only own these references in the 10.6+ API. */
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ CGDisplayModeRelease((CGDisplayModeRef) moderef);
+ }
+#endif
+}
+
+static void QZ_ReleaseDisplayModeList(_THIS, CFArrayRef mode_list)
+{
+ /* we only own these references in the 10.6+ API. */
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ CFRelease(mode_list);
+ }
+#endif
+}
+
+
+/* Bootstrap functions */
+static int QZ_Available ()
+{
+ return 1;
+}
+
+static SDL_VideoDevice* QZ_CreateDevice (int device_index)
+{
+#pragma unused (device_index)
+
+ SDL_VideoDevice *device;
+ SDL_PrivateVideoData *hidden;
+
+ device = (SDL_VideoDevice*) SDL_malloc (sizeof (*device) );
+ hidden = (SDL_PrivateVideoData*) SDL_malloc (sizeof (*hidden) );
+
+ if (device == NULL || hidden == NULL)
+ SDL_OutOfMemory ();
+
+ SDL_memset (device, 0, sizeof (*device) );
+ SDL_memset (hidden, 0, sizeof (*hidden) );
+
+ device->hidden = hidden;
+
+ device->VideoInit = QZ_VideoInit;
+ device->ListModes = QZ_ListModes;
+ device->SetVideoMode = QZ_SetVideoMode;
+ device->ToggleFullScreen = QZ_ToggleFullScreen;
+ device->UpdateMouse = QZ_UpdateMouse;
+ device->SetColors = QZ_SetColors;
+ /* device->UpdateRects = QZ_UpdateRects; this is determined by SetVideoMode() */
+ device->VideoQuit = QZ_VideoQuit;
+
+ device->LockHWSurface = QZ_LockHWSurface;
+ device->UnlockHWSurface = QZ_UnlockHWSurface;
+ device->AllocHWSurface = QZ_AllocHWSurface;
+ device->FreeHWSurface = QZ_FreeHWSurface;
+
+ device->SetGamma = QZ_SetGamma;
+ device->GetGamma = QZ_GetGamma;
+ device->SetGammaRamp = QZ_SetGammaRamp;
+ device->GetGammaRamp = QZ_GetGammaRamp;
+
+ device->GL_GetProcAddress = QZ_GL_GetProcAddress;
+ device->GL_GetAttribute = QZ_GL_GetAttribute;
+ device->GL_MakeCurrent = QZ_GL_MakeCurrent;
+ device->GL_SwapBuffers = QZ_GL_SwapBuffers;
+ device->GL_LoadLibrary = QZ_GL_LoadLibrary;
+
+ device->FreeWMCursor = QZ_FreeWMCursor;
+ device->CreateWMCursor = QZ_CreateWMCursor;
+ device->ShowWMCursor = QZ_ShowWMCursor;
+ device->WarpWMCursor = QZ_WarpWMCursor;
+ device->MoveWMCursor = QZ_MoveWMCursor;
+ device->CheckMouseMode = QZ_CheckMouseMode;
+ device->InitOSKeymap = QZ_InitOSKeymap;
+ device->PumpEvents = QZ_PumpEvents;
+
+ device->SetCaption = QZ_SetCaption;
+ device->SetIcon = QZ_SetIcon;
+ device->IconifyWindow = QZ_IconifyWindow;
+ device->SetWindowPos = QZ_SetWindowPos;
+ device->GetWindowPos = QZ_GetWindowPos;
+ device->IsWindowVisible = QZ_IsWindowVisible;
+ device->GetMonitorDPI = QZ_GetMonitorDPI;
+ device->GetMonitorRect = QZ_GetMonitorRect;
+ device->GetWMInfo = QZ_GetWMInfo;
+ device->GrabInput = QZ_GrabInput;
+
+ /*
+ * This is a big hassle, needing QuickDraw and QuickTime on older
+ * systems, and god knows what on 10.6, so we immediately fail here,
+ * which causes SDL to make an RGB surface and manage the YUV overlay
+ * in software. Sorry. Use SDL 1.3 if you want YUV rendering in a pixel
+ * shader. :)
+ */
+ /*device->CreateYUVOverlay = QZ_CreateYUVOverlay;*/
+
+ device->free = QZ_DeleteDevice;
+
+ return device;
+}
+
+static void QZ_DeleteDevice (SDL_VideoDevice *device)
+{
+ _THIS = device;
+ QZ_ReleaseDisplayMode(this, save_mode);
+ QZ_ReleaseDisplayMode(this, mode);
+ SDL_free (device->hidden);
+ SDL_free (device);
+}
+
+static void QZ_GetModeInfo(_THIS, const void *_mode, Uint32 *w, Uint32 *h, Uint32 *bpp)
+{
+ *w = *h = *bpp = 0;
+ if (_mode == NULL) {
+ return;
+ }
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ CGDisplayModeRef vidmode = (CGDisplayModeRef) _mode;
+ CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
+
+ *w = (Uint32) CGDisplayModeGetWidth(vidmode);
+ *h = (Uint32) CGDisplayModeGetHeight(vidmode);
+
+ /* we only care about the 32-bit modes... */
+ if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
+ kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ *bpp = 32;
+ }
+
+ CFRelease(fmt);
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
+ if (!use_new_mode_apis) {
+ CFDictionaryRef vidmode = (CFDictionaryRef) _mode;
+ CFNumberGetValue (
+ CFDictionaryGetValue (vidmode, kCGDisplayBitsPerPixel),
+ kCFNumberSInt32Type, bpp);
+
+ CFNumberGetValue (
+ CFDictionaryGetValue (vidmode, kCGDisplayWidth),
+ kCFNumberSInt32Type, w);
+
+ CFNumberGetValue (
+ CFDictionaryGetValue (vidmode, kCGDisplayHeight),
+ kCFNumberSInt32Type, h);
+ }
+#endif
+
+ /* we only care about the 32-bit modes... */
+ if (*bpp != 32) {
+ *bpp = 0;
+ }
+}
+
+static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format)
+{
+ NSRect r = NSMakeRect(0.0, 0.0, 0.0, 0.0);
+ const char *env = NULL;
+
+ if ( Gestalt(gestaltSystemVersion, &system_version) != noErr )
+ system_version = 0;
+
+ use_new_mode_apis = NO;
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ use_new_mode_apis = IS_SNOW_LEOPARD_OR_LATER(this);
+#endif
+
+ /* Initialize the video settings; this data persists between mode switches */
+ display_id = kCGDirectMainDisplay;
+
+#if 0 /* The mouse event code needs to take this into account... */
+ env = getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
+ if ( env ) {
+ int monitor = SDL_atoi(env);
+ CGDirectDisplayID activeDspys [3];
+ CGDisplayCount dspyCnt;
+ CGGetActiveDisplayList (3, activeDspys, &dspyCnt);
+ if ( monitor >= 0 && monitor < dspyCnt ) {
+ display_id = activeDspys[monitor];
+ }
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ save_mode = CGDisplayCopyDisplayMode(display_id);
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
+ if (!use_new_mode_apis) {
+ save_mode = CGDisplayCurrentMode(display_id);
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ if (!IS_LION_OR_LATER(this)) {
+ palette = CGPaletteCreateDefaultColorPalette();
+ }
+#endif
+
+ if (save_mode == NULL) {
+ SDL_SetError("Couldn't figure out current display mode.");
+ return -1;
+ }
+
+ /* Allow environment override of screensaver disable. */
+ env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
+ if ( env ) {
+ allow_screensaver = SDL_atoi(env);
+ } else {
+#ifdef SDL_VIDEO_DISABLE_SCREENSAVER
+ allow_screensaver = 0;
+#else
+ allow_screensaver = 1;
+#endif
+ }
+
+ /* Gather some information that is useful to know about the display */
+ QZ_GetModeInfo(this, save_mode, &device_width, &device_height, &device_bpp);
+ if (device_bpp == 0) {
+ QZ_ReleaseDisplayMode(this, save_mode);
+ save_mode = NULL;
+ SDL_SetError("Unsupported display mode");
+ return -1;
+ }
+
+ /* Determine the current screen size */
+ this->info.current_w = device_width;
+ this->info.current_h = device_height;
+
+ /* Determine the default screen depth */
+ video_format->BitsPerPixel = device_bpp;
+
+ /* Set misc globals */
+ current_grab_mode = SDL_GRAB_OFF;
+ cursor_should_be_visible = YES;
+ cursor_visible = YES;
+ current_mods = 0;
+ field_edit = [[SDLTranslatorResponder alloc] initWithFrame:r];
+
+ /* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */
+ QZ_RegisterForSleepNotifications (this);
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ return 0;
+}
+
+static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ CFArrayRef mode_list = NULL; /* list of available fullscreen modes */
+ CFIndex num_modes;
+ CFIndex i;
+
+ int list_size = 0;
+
+ /* Any windowed mode is acceptable */
+ if ( (flags & SDL_FULLSCREEN) == 0 )
+ return (SDL_Rect**)-1;
+
+ /* Free memory from previous call, if any */
+ if ( client_mode_list != NULL ) {
+ int i;
+
+ for (i = 0; client_mode_list[i] != NULL; i++)
+ SDL_free (client_mode_list[i]);
+
+ SDL_free (client_mode_list);
+ client_mode_list = NULL;
+ }
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ mode_list = CGDisplayCopyAllDisplayModes(display_id, NULL);
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
+ if (!use_new_mode_apis) {
+ mode_list = CGDisplayAvailableModes(display_id);
+ }
+#endif
+
+ num_modes = CFArrayGetCount (mode_list);
+
+ /* Build list of modes with the requested bpp */
+ for (i = 0; i < num_modes; i++) {
+ Uint32 width, height, bpp;
+ const void *onemode = CFArrayGetValueAtIndex(mode_list, i);
+
+ QZ_GetModeInfo(this, onemode, &width, &height, &bpp);
+
+ if (bpp && (bpp == format->BitsPerPixel)) {
+ int hasMode = SDL_FALSE;
+ int i;
+
+ /* Check if mode is already in the list */
+ for (i = 0; i < list_size; i++) {
+ if (client_mode_list[i]->w == width &&
+ client_mode_list[i]->h == height) {
+ hasMode = SDL_TRUE;
+ break;
+ }
+ }
+
+ /* Grow the list and add mode to the list */
+ if ( ! hasMode ) {
+ SDL_Rect *rect;
+
+ list_size++;
+
+ if (client_mode_list == NULL)
+ client_mode_list = (SDL_Rect**)
+ SDL_malloc (sizeof(*client_mode_list) * (list_size+1) );
+ else {
+ /* !!! FIXME: this leaks memory if SDL_realloc() fails! */
+ client_mode_list = (SDL_Rect**)
+ SDL_realloc (client_mode_list, sizeof(*client_mode_list) * (list_size+1));
+ }
+
+ rect = (SDL_Rect*) SDL_malloc (sizeof(**client_mode_list));
+
+ if (client_mode_list == NULL || rect == NULL) {
+ QZ_ReleaseDisplayModeList(this, mode_list);
+ SDL_OutOfMemory ();
+ return NULL;
+ }
+
+ rect->x = rect->y = 0;
+ rect->w = width;
+ rect->h = height;
+
+ client_mode_list[list_size-1] = rect;
+ client_mode_list[list_size] = NULL;
+ }
+ }
+ }
+
+ QZ_ReleaseDisplayModeList(this, mode_list);
+
+ /* Sort list largest to smallest (by area) */
+ {
+ int i, j;
+ for (i = 0; i < list_size; i++) {
+ for (j = 0; j < list_size-1; j++) {
+
+ int area1, area2;
+ area1 = client_mode_list[j]->w * client_mode_list[j]->h;
+ area2 = client_mode_list[j+1]->w * client_mode_list[j+1]->h;
+
+ if (area1 < area2) {
+ SDL_Rect *tmp = client_mode_list[j];
+ client_mode_list[j] = client_mode_list[j+1];
+ client_mode_list[j+1] = tmp;
+ }
+ }
+ }
+ }
+
+ return client_mode_list;
+}
+
+static SDL_bool QZ_WindowPosition(_THIS, int *x, int *y)
+{
+ const char *window = getenv("SDL_VIDEO_WINDOW_POS");
+ if ( window ) {
+ if ( sscanf(window, "%d,%d", x, y) == 2 ) {
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
+
+static CGError QZ_SetDisplayMode(_THIS, const void *vidmode)
+{
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ return CGDisplaySetDisplayMode(display_id, (CGDisplayModeRef) vidmode, NULL);
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
+ if (!use_new_mode_apis) {
+ return CGDisplaySwitchToMode(display_id, (CFDictionaryRef) vidmode);
+ }
+#endif
+
+ return kCGErrorFailure;
+}
+
+static inline CGError QZ_RestoreDisplayMode(_THIS)
+{
+ return QZ_SetDisplayMode(this, save_mode);
+}
+
+static void QZ_UnsetVideoMode (_THIS, BOOL to_desktop, BOOL save_gl)
+{
+ /* Reset values that may change between switches */
+ this->info.blit_fill = 0;
+ this->FillHWRect = NULL;
+ this->UpdateRects = NULL;
+ this->LockHWSurface = NULL;
+ this->UnlockHWSurface = NULL;
+
+ if (cg_context) {
+ CGContextFlush (cg_context);
+ CGContextRelease (cg_context);
+ cg_context = nil;
+ }
+
+ /* Release fullscreen resources */
+ if ( mode_flags & SDL_FULLSCREEN ) {
+
+ NSRect screen_rect;
+
+ /* Release double buffer stuff */
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ if ( !IS_LION_OR_LATER(this) && (mode_flags & SDL_DOUBLEBUF) ) {
+ quit_thread = YES;
+ SDL_SemPost (sem1);
+ SDL_WaitThread (thread, NULL);
+ SDL_DestroySemaphore (sem1);
+ SDL_DestroySemaphore (sem2);
+ SDL_free (sw_buffers[0]);
+ }
+#endif
+
+ /* If we still have a valid window, close it. */
+ if ( qz_window ) {
+ NSCAssert([ qz_window delegate ] == nil, @"full screen window shouldn't have a delegate"); /* if that should ever change, we'd have to release it here */
+ [ qz_window close ]; /* includes release because [qz_window isReleasedWhenClosed] */
+ qz_window = nil;
+ window_view = nil;
+ }
+ /*
+ Release the OpenGL context
+ Do this first to avoid trash on the display before fade
+ */
+ if ( mode_flags & SDL_OPENGL ) {
+ if (!save_gl) {
+ QZ_TearDownOpenGL (this);
+ }
+
+ #ifdef __powerpc__ /* we only use this for pre-10.3 compatibility. */
+ CGLSetFullScreen (NULL);
+ #endif
+ }
+ if (to_desktop) {
+ /* !!! FIXME: keep an eye on this.
+ * This API is officially unavailable for 64-bit binaries.
+ * It happens to work, as of 10.7, but we're going to see if
+ * we can just simply do without it on newer OSes...
+ */
+ #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
+ if ( !IS_LION_OR_LATER(this) ) {
+ ShowMenuBar ();
+ }
+ #endif
+
+ /* Restore original screen resolution/bpp */
+ QZ_RestoreDisplayMode (this);
+ CGReleaseAllDisplays ();
+ /*
+ Reset the main screen's rectangle
+ See comment in QZ_SetVideoFullscreen for why we do this
+ */
+ screen_rect = NSMakeRect(0,0,device_width,device_height);
+ QZ_SetFrame(this, [ NSScreen mainScreen ], screen_rect);
+ }
+ }
+ /* Release window mode resources */
+ else {
+ id delegate = [ qz_window delegate ];
+ [ qz_window close ]; /* includes release because [qz_window isReleasedWhenClosed] */
+ if (delegate != nil) [ delegate release ];
+ qz_window = nil;
+ window_view = nil;
+
+ /* Release the OpenGL context */
+ if ( mode_flags & SDL_OPENGL ) {
+ if (!save_gl) {
+ QZ_TearDownOpenGL (this);
+ }
+ }
+ }
+
+ /* Signal successful teardown */
+ video_set = SDL_FALSE;
+}
+
+static const void *QZ_BestMode(_THIS, const int bpp, const int w, const int h)
+{
+ const void *best = NULL;
+
+ if (bpp == 0) {
+ return NULL;
+ }
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
+ if (use_new_mode_apis) {
+ /* apparently, we have to roll our own now. :/ */
+ CFArrayRef mode_list = CGDisplayCopyAllDisplayModes(display_id, NULL);
+ if (mode_list != NULL) {
+ const CFIndex num_modes = CFArrayGetCount(mode_list);
+ CFIndex i;
+ for (i = 0; i < num_modes; i++) {
+ const void *vidmode = CFArrayGetValueAtIndex(mode_list, i);
+ Uint32 thisw, thish, thisbpp;
+ QZ_GetModeInfo(this, vidmode, &thisw, &thish, &thisbpp);
+
+ /* We only care about exact matches, apparently. */
+ if ((thisbpp == bpp) && (thisw == w) && (thish == h)) {
+ best = vidmode;
+ break; /* got it! */
+ }
+ }
+ CGDisplayModeRetain((CGDisplayModeRef) best); /* NULL is ok */
+ CFRelease(mode_list);
+ }
+ }
+#endif
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1060)
+ if (!use_new_mode_apis) {
+ boolean_t exact = 0;
+ best = CGDisplayBestModeForParameters(display_id, bpp, w, h, &exact);
+ if (!exact) {
+ best = NULL;
+ }
+ }
+#endif
+
+ return best;
+}
+
+static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
+ int height, int bpp, Uint32 flags,
+ const BOOL save_gl)
+{
+ const BOOL isLion = IS_LION_OR_LATER(this);
+ NSRect screen_rect;
+ CGError error;
+ NSRect contentRect;
+ CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
+
+ current->flags = SDL_FULLSCREEN;
+ current->w = width;
+ current->h = height;
+
+ contentRect = NSMakeRect (0, 0, width, height);
+
+ /* Fade to black to hide resolution-switching flicker (and garbage
+ that is displayed by a destroyed OpenGL context, if applicable) */
+ if ( CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess ) {
+ CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
+ }
+
+ /* Destroy any previous mode */
+ if (video_set == SDL_TRUE)
+ QZ_UnsetVideoMode (this, FALSE, save_gl);
+
+ /* Sorry, QuickDraw was ripped out. */
+ if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
+ SDL_SetError ("Embedded QuickDraw windows are no longer supported");
+ goto ERR_NO_MATCH;
+ }
+
+ QZ_ReleaseDisplayMode(this, mode); /* NULL is okay. */
+
+ /* See if requested mode exists */
+ mode = QZ_BestMode(this, bpp, width, height);
+
+ /* Require an exact match to the requested mode */
+ if ( mode == NULL ) {
+ SDL_SetError ("Failed to find display resolution: %dx%dx%d", width, height, bpp);
+ goto ERR_NO_MATCH;
+ }
+
+ /* Put up the blanking window (a window above all other windows) */
+ if (getenv ("SDL_SINGLEDISPLAY"))
+ error = CGDisplayCapture (display_id);
+ else
+ error = CGCaptureAllDisplays ();
+
+ if ( CGDisplayNoErr != error ) {
+ SDL_SetError ("Failed capturing display");
+ goto ERR_NO_CAPTURE;
+ }
+
+ /* Do the physical switch */
+ if ( CGDisplayNoErr != QZ_SetDisplayMode(this, mode) ) {
+ SDL_SetError ("Failed switching display resolution");
+ goto ERR_NO_SWITCH;
+ }
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ if ( !isLion ) {
+ current->pixels = (Uint32*) CGDisplayBaseAddress (display_id);
+ current->pitch = CGDisplayBytesPerRow (display_id);
+
+ current->flags |= SDL_HWSURFACE;
+ current->flags |= SDL_PREALLOC;
+ /* current->hwdata = (void *) CGDisplayGetDrawingContext (display_id); */
+
+ this->UpdateRects = QZ_DirectUpdate;
+ this->LockHWSurface = QZ_LockHWSurface;
+ this->UnlockHWSurface = QZ_UnlockHWSurface;
+
+ /* Setup double-buffer emulation */
+ if ( flags & SDL_DOUBLEBUF ) {
+
+ /*
+ Setup a software backing store for reasonable results when
+ double buffering is requested (since a single-buffered hardware
+ surface looks hideous).
+
+ The actual screen blit occurs in a separate thread to allow
+ other blitting while waiting on the VBL (and hence results in higher framerates).
+ */
+ this->LockHWSurface = NULL;
+ this->UnlockHWSurface = NULL;
+ this->UpdateRects = NULL;
+
+ current->flags |= (SDL_HWSURFACE|SDL_DOUBLEBUF);
+ this->UpdateRects = QZ_DoubleBufferUpdate;
+ this->LockHWSurface = QZ_LockDoubleBuffer;
+ this->UnlockHWSurface = QZ_UnlockDoubleBuffer;
+ this->FlipHWSurface = QZ_FlipDoubleBuffer;
+
+ current->pixels = SDL_malloc (current->pitch * current->h * 2);
+ if (current->pixels == NULL) {
+ SDL_OutOfMemory ();
+ goto ERR_DOUBLEBUF;
+ }
+
+ sw_buffers[0] = current->pixels;
+ sw_buffers[1] = (Uint8*)current->pixels + current->pitch * current->h;
+
+ quit_thread = NO;
+ sem1 = SDL_CreateSemaphore (0);
+ sem2 = SDL_CreateSemaphore (1);
+ thread = SDL_CreateThread ((int (*)(void *))QZ_ThreadFlip, this);
+ }
+
+ if ( CGDisplayCanSetPalette (display_id) )
+ current->flags |= SDL_HWPALETTE;
+ }
+#endif
+
+ /* Check if we should recreate the window */
+ if (qz_window == nil) {
+ /* Manually create a window, avoids having a nib file resource */
+ qz_window = [ [ SDL_QuartzWindow alloc ]
+ initWithContentRect:contentRect
+ styleMask:(isLion ? NSBorderlessWindowMask : 0)
+ backing:NSBackingStoreBuffered
+ defer:NO ];
+
+ if (qz_window != nil) {
+ [ qz_window setAcceptsMouseMovedEvents:YES ];
+ [ qz_window setViewsNeedDisplay:NO ];
+ if (isLion) {
+ [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ];
+ }
+ }
+ }
+ /* We already have a window, just change its size */
+ else {
+ [ qz_window setContentSize:contentRect.size ];
+ current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
+ [ window_view setFrameSize:contentRect.size ];
+ }
+
+ /* Setup OpenGL for a fullscreen context */
+ if (flags & SDL_OPENGL) {
+
+ if ( ! save_gl ) {
+ if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
+ goto ERR_NO_GL;
+ }
+ }
+
+ /* Initialize the NSView and add it to our window. The presence of a valid window and
+ view allow the cursor to be changed whilst in fullscreen.*/
+ window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
+
+ if ( isLion ) {
+ [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ }
+
+ [ [ qz_window contentView ] addSubview:window_view ];
+
+ /* Apparently Lion checks some version flag set by the linker
+ and changes API behavior. Annoying. */
+ if ( isLion ) {
+ [ qz_window setLevel:CGShieldingWindowLevel() ];
+ [ gl_context setView: window_view ];
+ //[ gl_context setFullScreen ];
+ [ gl_context update ];
+ }
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ if ( !isLion ) {
+ CGLError err;
+ CGLContextObj ctx;
+
+ [ qz_window setLevel:NSNormalWindowLevel ];
+ ctx = QZ_GetCGLContextObj (gl_context);
+ err = CGLSetFullScreen (ctx);
+
+ if (err) {
+ SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err));
+ goto ERR_NO_GL;
+ }
+ }
+#endif
+
+ [ window_view release ];
+ [ gl_context makeCurrentContext];
+
+ glClear (GL_COLOR_BUFFER_BIT);
+
+ [ gl_context flushBuffer ];
+
+ current->flags |= SDL_OPENGL;
+ } else if (isLion) { /* For 2D, we build a CGBitmapContext */
+ CGColorSpaceRef cgColorspace;
+
+ /* Only recreate the view if it doesn't already exist */
+ if (window_view == nil) {
+ window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
+ [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ [ [ qz_window contentView ] addSubview:window_view ];
+ [ window_view release ];
+ }
+
+ cgColorspace = CGColorSpaceCreateDeviceRGB();
+ current->pitch = 4 * current->w;
+ current->pixels = SDL_malloc (current->h * current->pitch);
+
+ cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h,
+ 8, current->pitch, cgColorspace,
+ kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease (cgColorspace);
+
+ current->flags |= SDL_SWSURFACE;
+ current->flags |= SDL_ASYNCBLIT;
+ current->hwdata = (void *) cg_context;
+
+ /* Force this window to draw above _everything_. */
+ [ qz_window setLevel:CGShieldingWindowLevel() ];
+
+ this->UpdateRects = QZ_UpdateRects;
+ this->LockHWSurface = QZ_LockHWSurface;
+ this->UnlockHWSurface = QZ_UnlockHWSurface;
+ }
+
+ if (isLion) {
+ [ qz_window setHasShadow:NO];
+ [ qz_window setOpaque:YES];
+ [ qz_window makeKeyAndOrderFront:nil ];
+ }
+
+ /* !!! FIXME: keep an eye on this.
+ * This API is officially unavailable for 64-bit binaries.
+ * It happens to work, as of 10.7, but we're going to see if
+ * we can just simply do without it on newer OSes...
+ */
+ #if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__)
+ if ( !isLion ) {
+ /* If we don't hide menu bar, it will get events and interrupt the program */
+ HideMenuBar ();
+ }
+ #endif
+
+ /* Fade in again (asynchronously) */
+ if ( fade_token != kCGDisplayFadeReservationInvalidToken ) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation(fade_token);
+ }
+
+ /*
+ There is a bug in Cocoa where NSScreen doesn't synchronize
+ with CGDirectDisplay, so the main screen's frame is wrong.
+ As a result, coordinate translation produces incorrect results.
+ We can hack around this bug by setting the screen rect
+ ourselves. This hack should be removed if/when the bug is fixed.
+ */
+ screen_rect = NSMakeRect(0,0,width,height);
+ QZ_SetFrame(this, [ NSScreen mainScreen ], screen_rect);
+
+ /* Save the flags to ensure correct tear-down */
+ mode_flags = current->flags;
+
+ /* Set app state, hide cursor if necessary, ... */
+ QZ_DoActivate(this);
+
+ return current;
+
+ /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
+ERR_NO_GL: goto ERR_DOUBLEBUF; /* this goto is to stop a compiler warning on newer SDKs. */
+ERR_DOUBLEBUF: QZ_RestoreDisplayMode(this);
+ERR_NO_SWITCH: CGReleaseAllDisplays ();
+ERR_NO_CAPTURE:
+ERR_NO_MATCH: if ( fade_token != kCGDisplayFadeReservationInvalidToken ) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+ return NULL;
+}
+
+static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
+ int height, int *bpp, Uint32 flags,
+ const BOOL save_gl)
+{
+ unsigned int style;
+ NSRect contentRect;
+ int center_window = 1;
+ int origin_x, origin_y;
+ CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
+
+ current->flags = 0;
+ current->w = width;
+ current->h = height;
+
+ contentRect = NSMakeRect (0, 0, width, height);
+
+ /*
+ Check if we should completely destroy the previous mode
+ - If it is fullscreen
+ - If it has different noframe or resizable attribute
+ - If it is OpenGL (since gl attributes could be different)
+ - If new mode is OpenGL, but previous mode wasn't
+ */
+ if (video_set == SDL_TRUE) {
+ if (mode_flags & SDL_FULLSCREEN) {
+ /* Fade to black to hide resolution-switching flicker (and garbage
+ that is displayed by a destroyed OpenGL context, if applicable) */
+ if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) {
+ CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
+ }
+ QZ_UnsetVideoMode (this, TRUE, save_gl);
+ }
+ else if ( ((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) ||
+ (mode_flags & SDL_OPENGL) ||
+ (flags & SDL_OPENGL) ) {
+ QZ_UnsetVideoMode (this, TRUE, save_gl);
+ }
+ }
+
+ /* Sorry, QuickDraw was ripped out. */
+ if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
+ SDL_SetError ("Embedded QuickDraw windows are no longer supported");
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+ return NULL;
+ }
+
+ /* Check if we should recreate the window */
+ if (qz_window == nil) {
+
+ /* Set the window style based on input flags */
+ if ( flags & SDL_NOFRAME ) {
+ style = NSBorderlessWindowMask;
+ current->flags |= SDL_NOFRAME;
+ } else {
+ style = NSTitledWindowMask;
+ style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
+ if ( flags & SDL_RESIZABLE ) {
+ style |= NSResizableWindowMask;
+ current->flags |= SDL_RESIZABLE;
+ }
+ }
+
+ /* Manually create a window, avoids having a nib file resource */
+ qz_window = [ [ SDL_QuartzWindow alloc ]
+ initWithContentRect:contentRect
+ styleMask:style
+ backing:NSBackingStoreBuffered
+ defer:NO ];
+
+ if (qz_window == nil) {
+ SDL_SetError ("Could not create the Cocoa window");
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+ return NULL;
+ }
+
+ /*[ qz_window setReleasedWhenClosed:YES ];*/ /* no need to set this as it's the default for NSWindows */
+ QZ_SetCaption(this, this->wm_title, this->wm_icon);
+ [ qz_window setAcceptsMouseMovedEvents:YES ];
+ [ qz_window setViewsNeedDisplay:NO ];
+
+ if ( QZ_WindowPosition(this, &origin_x, &origin_y) ) {
+ /* have to flip the Y value (NSPoint is lower left corner origin) */
+ [ qz_window setFrameTopLeftPoint:NSMakePoint((float) origin_x, (float) (this->info.current_h - origin_y))];
+ center_window = 0;
+ } else if ( center_window ) {
+ [ qz_window center ];
+ }
+
+ [ qz_window setDelegate:
+ [ [ SDL_QuartzWindowDelegate alloc ] init ] ];
+ [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ];
+ }
+ /* We already have a window, just change its size */
+ else {
+ [ qz_window setContentSize:contentRect.size ];
+ current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
+ [ window_view setFrameSize:contentRect.size ];
+ }
+
+ /* For OpenGL, we bind the context to a subview */
+ if ( flags & SDL_OPENGL ) {
+
+ if ( ! save_gl ) {
+ if ( ! QZ_SetupOpenGL (this, *bpp, flags) ) {
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+ return NULL;
+ }
+ }
+
+ window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
+ [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ [ [ qz_window contentView ] addSubview:window_view ];
+ [ gl_context setView: window_view ];
+ [ window_view release ];
+ [ gl_context makeCurrentContext];
+ [ qz_window makeKeyAndOrderFront:nil ];
+ current->flags |= SDL_OPENGL;
+ }
+ /* For 2D, we build a CGBitmapContext */
+ else {
+ CGColorSpaceRef cgColorspace;
+
+ /* Only recreate the view if it doesn't already exist */
+ if (window_view == nil) {
+
+ window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
+ [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
+ [ [ qz_window contentView ] addSubview:window_view ];
+ [ window_view release ];
+ [ qz_window makeKeyAndOrderFront:nil ];
+ }
+
+ cgColorspace = CGColorSpaceCreateDeviceRGB();
+ current->pitch = 4 * current->w;
+ current->pixels = SDL_malloc (current->h * current->pitch);
+
+ cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h,
+ 8, current->pitch, cgColorspace,
+ kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease (cgColorspace);
+
+ current->flags |= SDL_SWSURFACE;
+ current->flags |= SDL_ASYNCBLIT;
+ current->hwdata = (void *) cg_context;
+
+ this->UpdateRects = QZ_UpdateRects;
+ this->LockHWSurface = QZ_LockHWSurface;
+ this->UnlockHWSurface = QZ_UnlockHWSurface;
+ }
+
+ /* Save flags to ensure correct teardown */
+ mode_flags = current->flags;
+
+ /* Fade in again (asynchronously) if we came from a fullscreen mode and faded to black */
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+
+ return current;
+}
+
+
+static SDL_Surface* QZ_SetVideoModeInternal (_THIS, SDL_Surface *current,
+ int width, int height, int bpp,
+ Uint32 flags, BOOL save_gl)
+{
+ const BOOL isLion = IS_LION_OR_LATER(this);
+
+ current->flags = 0;
+ current->pixels = NULL;
+
+ /* Setup full screen video */
+ if ( flags & SDL_FULLSCREEN ) {
+ if ( isLion ) {
+ bpp = 32;
+ }
+ current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags, save_gl );
+ if (current == NULL)
+ return NULL;
+ }
+ /* Setup windowed video */
+ else {
+ /* Force bpp to 32 */
+ bpp = 32;
+ current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags, save_gl );
+ if (current == NULL)
+ return NULL;
+ }
+
+ if (qz_window != nil) {
+ nsgfx_context = [NSGraphicsContext graphicsContextWithWindow:qz_window];
+ [NSGraphicsContext setCurrentContext:nsgfx_context];
+ }
+
+ /* Setup the new pixel format */
+ {
+ int amask = 0,
+ rmask = 0,
+ gmask = 0,
+ bmask = 0;
+
+ switch (bpp) {
+ case 16: /* (1)-5-5-5 RGB */
+ amask = 0;
+ rmask = 0x7C00;
+ gmask = 0x03E0;
+ bmask = 0x001F;
+ break;
+ case 24:
+ SDL_SetError ("24bpp is not available");
+ return NULL;
+ case 32: /* (8)-8-8-8 ARGB */
+ amask = 0x00000000;
+ if ( (!isLion) && (flags & SDL_FULLSCREEN) ) {
+ rmask = 0x00FF0000;
+ gmask = 0x0000FF00;
+ bmask = 0x000000FF;
+ } else {
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ rmask = 0x0000FF00;
+ gmask = 0x00FF0000;
+ bmask = 0xFF000000;
+#else
+ rmask = 0x00FF0000;
+ gmask = 0x0000FF00;
+ bmask = 0x000000FF;
+#endif
+ break;
+ }
+ }
+
+ if ( ! SDL_ReallocFormat (current, bpp,
+ rmask, gmask, bmask, amask ) ) {
+ SDL_SetError ("Couldn't reallocate pixel format");
+ return NULL;
+ }
+ }
+
+ /* Signal successful completion (used internally) */
+ video_set = SDL_TRUE;
+
+ return current;
+}
+
+static SDL_Surface* QZ_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp,
+ Uint32 flags)
+{
+ /* Don't throw away the GL context if we can just resize the current one. */
+#if 0 /* !!! FIXME: half-finished side project. Reenable this if you ever debug the corner cases. */
+ const BOOL save_gl = ( (video_set == SDL_TRUE) && ((flags & SDL_OPENGL) == (current->flags & SDL_OPENGL)) && (bpp == current->format->BitsPerPixel) );
+#else
+ const BOOL save_gl = NO;
+#endif
+
+ NSOpenGLContext *glctx = gl_context;
+ SDL_Surface* retval = NULL;
+
+ if (save_gl) {
+ [glctx retain]; /* just so we don't lose this when killing old views, etc */
+ }
+
+ retval = QZ_SetVideoModeInternal (this, current, width, height, bpp, flags, save_gl);
+
+ if (save_gl) {
+ [glctx release]; /* something else should own this now, or we legitimately release it. */
+ }
+
+ return retval;
+}
+
+
+static int QZ_ToggleFullScreen (_THIS, int on)
+{
+ return 0;
+}
+
+static int QZ_SetColors (_THIS, int first_color, int num_colors,
+ SDL_Color *colors)
+{
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ /* we shouldn't have an 8-bit mode on Lion! */
+ if (!IS_LION_OR_LATER(this)) {
+ CGTableCount index;
+ CGDeviceColor color;
+
+ for (index = first_color; index < first_color+num_colors; index++) {
+
+ /* Clamp colors between 0.0 and 1.0 */
+ color.red = colors->r / 255.0;
+ color.blue = colors->b / 255.0;
+ color.green = colors->g / 255.0;
+
+ colors++;
+
+ CGPaletteSetColorAtIndex (palette, color, index);
+ }
+
+ return ( CGDisplayNoErr == CGDisplaySetPalette (display_id, palette) );
+ }
+#endif
+
+ return 0;
+}
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+static int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface)
+{
+ return 1;
+}
+
+static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface)
+{
+}
+
+/* The VBL delay is based on code by Ian R Ollmann's RezLib <iano@cco.caltech.edu> */
+static AbsoluteTime QZ_SecondsToAbsolute ( double seconds )
+{
+ union
+ {
+ UInt64 i;
+ Nanoseconds ns;
+ } temp;
+
+ temp.i = seconds * 1000000000.0;
+
+ return NanosecondsToAbsolute ( temp.ns );
+}
+
+static int QZ_ThreadFlip (_THIS)
+{
+ Uint8 *src, *dst;
+ int skip, len, h;
+
+ /*
+ Give this thread the highest scheduling priority possible,
+ in the hopes that it will immediately run after the VBL delay
+ */
+ {
+ pthread_t current_thread;
+ int policy;
+ struct sched_param param;
+
+ current_thread = pthread_self ();
+ pthread_getschedparam (current_thread, &policy, &param);
+ policy = SCHED_RR;
+ param.sched_priority = sched_get_priority_max (policy);
+ pthread_setschedparam (current_thread, policy, &param);
+ }
+
+ while (1) {
+
+ SDL_SemWait (sem1);
+ if (quit_thread)
+ return 0;
+
+ /*
+ * We have to add SDL_VideoSurface->offset here, since we might be a
+ * smaller surface in the center of the framebuffer (you asked for
+ * a fullscreen resolution smaller than the hardware could supply
+ * so SDL is centering it in a bigger resolution)...
+ */
+ dst = ((Uint8 *)((size_t)CGDisplayBaseAddress (display_id))) + SDL_VideoSurface->offset;
+ src = current_buffer + SDL_VideoSurface->offset;
+ len = SDL_VideoSurface->w * SDL_VideoSurface->format->BytesPerPixel;
+ h = SDL_VideoSurface->h;
+ skip = SDL_VideoSurface->pitch;
+
+ /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
+ {
+
+ /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
+ double refreshRate;
+ double linesPerSecond;
+ double target;
+ double position;
+ double adjustment;
+ AbsoluteTime nextTime;
+ CFNumberRef refreshRateCFNumber;
+
+ refreshRateCFNumber = CFDictionaryGetValue (mode, kCGDisplayRefreshRate);
+ if ( NULL == refreshRateCFNumber ) {
+ SDL_SetError ("Mode has no refresh rate");
+ goto ERROR;
+ }
+
+ if ( 0 == CFNumberGetValue (refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) ) {
+ SDL_SetError ("Error getting refresh rate");
+ goto ERROR;
+ }
+
+ if ( 0 == refreshRate ) {
+
+ SDL_SetError ("Display has no refresh rate, using 60hz");
+
+ /* ok, for LCD's we'll emulate a 60hz refresh, which may or may not look right */
+ refreshRate = 60.0;
+ }
+
+ linesPerSecond = refreshRate * h;
+ target = h;
+
+ /* Figure out the first delay so we start off about right */
+ position = CGDisplayBeamPosition (display_id);
+ if (position > target)
+ position = 0;
+
+ adjustment = (target - position) / linesPerSecond;
+
+ nextTime = AddAbsoluteToAbsolute (UpTime (), QZ_SecondsToAbsolute (adjustment));
+
+ MPDelayUntil (&nextTime);
+ }
+
+
+ /* On error, skip VBL delay */
+ ERROR:
+
+ /* TODO: use CGContextDrawImage here too! Create two CGContextRefs the same way we
+ create two buffers, replace current_buffer with current_context and set it
+ appropriately in QZ_FlipDoubleBuffer. */
+ while ( h-- ) {
+
+ SDL_memcpy (dst, src, len);
+ src += skip;
+ dst += skip;
+ }
+
+ /* signal flip completion */
+ SDL_SemPost (sem2);
+ }
+
+ return 0;
+}
+
+static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface)
+{
+ /* wait for previous flip to complete */
+ SDL_SemWait (sem2);
+
+ current_buffer = surface->pixels;
+
+ if (surface->pixels == sw_buffers[0])
+ surface->pixels = sw_buffers[1];
+ else
+ surface->pixels = sw_buffers[0];
+
+ /* signal worker thread to do the flip */
+ SDL_SemPost (sem1);
+
+ return 0;
+}
+
+static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects)
+{
+ /* perform a flip if someone calls updaterects on a doublebuferred surface */
+ this->FlipHWSurface (this, SDL_VideoSurface);
+}
+
+static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects)
+{
+#pragma unused(this,num_rects,rects)
+}
+#endif
+
+/* Resize icon, BMP format */
+static const unsigned char QZ_ResizeIcon[] = {
+ 0x42,0x4d,0x31,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
+ 0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
+ 0x00,0x00,0xfb,0x01,0x00,0x00,0x13,0x0b,0x00,0x00,0x13,0x0b,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,
+ 0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
+ 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xda,0xda,0xda,0x87,
+ 0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,
+ 0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xd5,0xd5,0x87,0x87,0x87,0xe8,0xe8,0xe8,
+ 0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,
+ 0xda,0xda,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,
+ 0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,
+ 0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
+ 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,
+ 0xe8,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xd9,0xd9,0xd9,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xdc,
+ 0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,
+ 0xdb,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,0xdb,0x87,0x87,0x87,0xe8,
+ 0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdc,
+ 0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b
+};
+
+static void QZ_DrawResizeIcon (_THIS)
+{
+ /* Check if we should draw the resize icon */
+ if (SDL_VideoSurface->flags & SDL_RESIZABLE) {
+
+ SDL_Rect icon_rect;
+
+ /* Create the icon image */
+ if (resize_icon == NULL) {
+
+ SDL_RWops *rw;
+ SDL_Surface *tmp;
+
+ rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
+ tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
+
+ resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
+ SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
+
+ SDL_FreeSurface (tmp);
+ }
+
+ icon_rect.x = SDL_VideoSurface->w - 13;
+ icon_rect.y = SDL_VideoSurface->h - 13;
+ icon_rect.w = 13;
+ icon_rect.h = 13;
+
+ SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
+ }
+}
+
+static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects)
+{
+ if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
+ QZ_GL_SwapBuffers (this);
+ }
+ else if ( [ qz_window isMiniaturized ] ) {
+
+ /* Do nothing if miniaturized */
+ }
+
+ else {
+ NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+ if (ctx != nsgfx_context) { /* uhoh, you might be rendering from another thread... */
+ [NSGraphicsContext setCurrentContext:nsgfx_context];
+ ctx = nsgfx_context;
+ }
+ CGContextRef cgc = (CGContextRef) [ctx graphicsPort];
+ QZ_DrawResizeIcon (this);
+ CGContextFlush (cg_context);
+ CGImageRef image = CGBitmapContextCreateImage (cg_context);
+ CGRect rectangle = CGRectMake (0,0,[window_view frame].size.width,[window_view frame].size.height);
+
+ CGContextDrawImage (cgc, rectangle, image);
+ CGImageRelease(image);
+ CGContextFlush (cgc);
+ }
+}
+
+static void QZ_VideoQuit (_THIS)
+{
+ CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
+
+ /* Restore gamma settings */
+ CGDisplayRestoreColorSyncSettings ();
+
+ /* Ensure the cursor will be visible and working when we quit */
+ CGDisplayShowCursor (display_id);
+ CGAssociateMouseAndMouseCursorPosition (1);
+
+ if (mode_flags & SDL_FULLSCREEN) {
+ /* Fade to black to hide resolution-switching flicker (and garbage
+ that is displayed by a destroyed OpenGL context, if applicable) */
+ if (CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess) {
+ CGDisplayFade (fade_token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
+ }
+ QZ_UnsetVideoMode (this, TRUE, FALSE);
+ if (fade_token != kCGDisplayFadeReservationInvalidToken) {
+ CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
+ CGReleaseDisplayFadeReservation (fade_token);
+ }
+ }
+ else
+ QZ_UnsetVideoMode (this, TRUE, FALSE);
+
+#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070)
+ if (!IS_LION_OR_LATER(this)) {
+ CGPaletteRelease(palette);
+ }
+#endif
+
+ if (opengl_library) {
+ SDL_UnloadObject(opengl_library);
+ opengl_library = NULL;
+ }
+ this->gl_config.driver_loaded = 0;
+
+ if (field_edit) {
+ [field_edit release];
+ field_edit = NULL;
+ }
+}
+
+static int QZ_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return 1;
+}
+
+static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+}
+
+static int QZ_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1); /* unallowed (no HWSURFACE support here). */
+}
+
+static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface)
+{
+}
+
+/* Gamma functions */
+int QZ_SetGamma (_THIS, float red, float green, float blue)
+{
+ const CGGammaValue min = 0.0, max = 1.0;
+
+ if (red == 0.0)
+ red = FLT_MAX;
+ else
+ red = 1.0 / red;
+
+ if (green == 0.0)
+ green = FLT_MAX;
+ else
+ green = 1.0 / green;
+
+ if (blue == 0.0)
+ blue = FLT_MAX;
+ else
+ blue = 1.0 / blue;
+
+ if ( CGDisplayNoErr == CGSetDisplayTransferByFormula
+ (display_id, min, max, red, min, max, green, min, max, blue) ) {
+
+ return 0;
+ }
+ else {
+
+ return -1;
+ }
+}
+
+int QZ_GetGamma (_THIS, float *red, float *green, float *blue)
+{
+ CGGammaValue dummy;
+ if ( CGDisplayNoErr == CGGetDisplayTransferByFormula
+ (display_id, &dummy, &dummy, red,
+ &dummy, &dummy, green, &dummy, &dummy, blue) )
+
+ return 0;
+ else
+ return -1;
+}
+
+int QZ_SetGammaRamp (_THIS, Uint16 *ramp)
+{
+ const uint32_t tableSize = 255;
+ CGGammaValue redTable[tableSize];
+ CGGammaValue greenTable[tableSize];
+ CGGammaValue blueTable[tableSize];
+
+ int i;
+
+ /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
+ for (i = 0; i < 256; i++)
+ redTable[i % 256] = ramp[i] / 65535.0;
+
+ for (i=256; i < 512; i++)
+ greenTable[i % 256] = ramp[i] / 65535.0;
+
+ for (i=512; i < 768; i++)
+ blueTable[i % 256] = ramp[i] / 65535.0;
+
+ if ( CGDisplayNoErr == CGSetDisplayTransferByTable
+ (display_id, tableSize, redTable, greenTable, blueTable) )
+ return 0;
+ else
+ return -1;
+}
+
+int QZ_GetGammaRamp (_THIS, Uint16 *ramp)
+{
+ const uint32_t tableSize = 255;
+ CGGammaValue redTable[tableSize];
+ CGGammaValue greenTable[tableSize];
+ CGGammaValue blueTable[tableSize];
+ uint32_t actual;
+ int i;
+
+ if ( CGDisplayNoErr != CGGetDisplayTransferByTable
+ (display_id, tableSize, redTable, greenTable, blueTable, &actual) ||
+ actual != tableSize)
+
+ return -1;
+
+ /* Pack tables into one array, with values from 0 to 65535 */
+ for (i = 0; i < 256; i++)
+ ramp[i] = redTable[i % 256] * 65535.0;
+
+ for (i=256; i < 512; i++)
+ ramp[i] = greenTable[i % 256] * 65535.0;
+
+ for (i=512; i < 768; i++)
+ ramp[i] = blueTable[i % 256] * 65535.0;
+
+ return 0;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h
new file mode 100644
index 0000000..5219a59
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h
@@ -0,0 +1,28 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+struct WMcursor {
+ NSCursor *nscursor;
+};
+
+void QZ_UpdateCursor(_THIS);
+int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m
new file mode 100644
index 0000000..b40abf8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m
@@ -0,0 +1,574 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWM.h"
+
+
+void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {
+
+ if ( cursor != NULL ) {
+ [ cursor->nscursor release ];
+ free (cursor);
+ }
+}
+
+WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
+ int w, int h, int hot_x, int hot_y) {
+ WMcursor *cursor;
+ NSBitmapImageRep *imgrep;
+ NSImage *img;
+ unsigned char *planes[5];
+ int i;
+ NSAutoreleasePool *pool;
+
+ pool = [ [ NSAutoreleasePool alloc ] init ];
+
+ /* Allocate the cursor memory */
+ cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
+ if (cursor == NULL) goto outOfMemory;
+
+ /* create the image representation and get the pointers to its storage */
+ imgrep = [ [ [ NSBitmapImageRep alloc ] initWithBitmapDataPlanes: NULL pixelsWide: w pixelsHigh: h bitsPerSample: 1 samplesPerPixel: 2 hasAlpha: YES isPlanar: YES colorSpaceName: NSDeviceWhiteColorSpace bytesPerRow: (w+7)/8 bitsPerPixel: 0 ] autorelease ];
+ if (imgrep == nil) goto outOfMemory;
+ [ imgrep getBitmapDataPlanes: planes ];
+
+ /* copy data and mask, extending the mask to all black pixels because the inversion effect doesn't work with Cocoa's alpha-blended cursors */
+ for (i = 0; i < (w+7)/8*h; i++) {
+ planes[0][i] = data[i] ^ 0xFF;
+ planes[1][i] = mask[i] | data[i];
+ }
+
+ /* create image and cursor */
+ img = [ [ [ NSImage alloc ] initWithSize: NSMakeSize(w, h) ] autorelease ];
+ if (img == nil) goto outOfMemory;
+ [ img addRepresentation: imgrep ];
+ if (system_version < 0x1030) { /* on 10.2, cursors must be 16*16 */
+ if (w > 16 || h > 16) { /* too big: scale it down */
+ [ img setScalesWhenResized: YES ];
+ hot_x = hot_x*16/w;
+ hot_y = hot_y*16/h;
+ }
+ else { /* too small (or just right): extend it (from the bottom left corner, so hot_y must be adjusted) */
+ hot_y += 16 - h;
+ }
+ [ img setSize: NSMakeSize(16, 16) ];
+ }
+ cursor->nscursor = [ [ NSCursor alloc ] initWithImage: img hotSpot: NSMakePoint(hot_x, hot_y) ];
+ if (cursor->nscursor == nil) goto outOfMemory;
+
+ [ pool release ];
+ return(cursor);
+
+outOfMemory:
+ [ pool release ];
+ if (cursor != NULL) SDL_free(cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+}
+
+void QZ_UpdateCursor (_THIS) {
+ BOOL state;
+
+ if (cursor_should_be_visible || !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
+ state = YES;
+ } else {
+ state = NO;
+ }
+ if (state != cursor_visible) {
+ if (state) {
+ [ NSCursor unhide ];
+ } else {
+ [ NSCursor hide ];
+ }
+ cursor_visible = state;
+ }
+}
+
+BOOL QZ_IsMouseInWindow (_THIS) {
+ if (qz_window == nil || (mode_flags & SDL_FULLSCREEN)) return YES; /*fullscreen*/
+ else {
+ NSPoint p = [ qz_window mouseLocationOutsideOfEventStream ];
+ p.y -= 1.0f; /* Apparently y goes from 1 to h, not from 0 to h-1 (i.e. the "location of the mouse" seems to be defined as "the location of the top left corner of the mouse pointer's hot pixel" */
+ return NSPointInRect(p, [ window_view frame ]);
+ }
+}
+
+int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
+
+ if ( cursor == NULL) {
+ if ( cursor_should_be_visible ) {
+ cursor_should_be_visible = NO;
+ QZ_ChangeGrabState (this, QZ_HIDECURSOR);
+ }
+ QZ_UpdateCursor(this);
+ }
+ else {
+ if ( qz_window != nil && !(mode_flags & SDL_FULLSCREEN) ) {
+ [ qz_window invalidateCursorRectsForView: [ qz_window contentView ] ];
+ }
+ if ( ! cursor_should_be_visible ) {
+ cursor_should_be_visible = YES;
+ QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
+ }
+ [ cursor->nscursor performSelectorOnMainThread:@selector(set) withObject:nil waitUntilDone:NO ];
+ QZ_UpdateCursor(this);
+ }
+
+ return 1;
+}
+
+/*
+ Coordinate conversion functions, for convenience
+ Cocoa sets the origin at the lower left corner of the window/screen
+ SDL, CoreGraphics/WindowServer, and QuickDraw use the origin at the upper left corner
+ The routines were written so they could be called before SetVideoMode() has finished;
+ this might have limited usefulness at the moment, but the extra cost is trivial.
+*/
+
+/* Convert Cocoa screen coordinate to Cocoa window coordinate */
+void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
+
+ if ( ! CGDisplayIsCaptured (display_id) )
+ *p = [ qz_window convertScreenToBase:*p ];
+}
+
+
+/* Convert Cocoa window coordinate to Cocoa screen coordinate */
+void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
+
+ if ( ! CGDisplayIsCaptured (display_id) )
+ *p = [ qz_window convertBaseToScreen:*p ];
+}
+
+/* Convert SDL coordinate to Cocoa coordinate */
+void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
+
+ if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
+
+ p->y = CGDisplayPixelsHigh (display_id) - p->y;
+ }
+ else {
+
+ *p = [ window_view convertPoint:*p toView: nil ];
+ p->y = [window_view frame].size.height - p->y;
+ }
+}
+
+/* Convert Cocoa coordinate to SDL coordinate */
+void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
+
+ if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
+
+ p->y = CGDisplayPixelsHigh (display_id) - p->y;
+ }
+ else {
+
+ *p = [ window_view convertPoint:*p fromView: nil ];
+ p->y = [window_view frame].size.height - p->y;
+ }
+}
+
+/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
+CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
+
+ CGPoint cgp;
+
+ if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
+
+ int height;
+
+ QZ_PrivateSDLToCocoa (this, p);
+ QZ_PrivateLocalToGlobal (this, p);
+
+ height = CGDisplayPixelsHigh (display_id);
+ p->y = height - p->y;
+ }
+
+ cgp.x = p->x;
+ cgp.y = p->y;
+
+ return cgp;
+}
+
+#if 0 /* Dead code */
+/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
+void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
+
+ if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
+
+ int height;
+
+ /* Convert CG Global to Cocoa Global */
+ height = CGDisplayPixelsHigh (display_id);
+ p->y = height - p->y;
+
+ QZ_PrivateGlobalToLocal (this, p);
+ QZ_PrivateCocoaToSDL (this, p);
+ }
+}
+#endif /* Dead code */
+
+void QZ_PrivateWarpCursor (_THIS, int x, int y) {
+ NSPoint p;
+ CGPoint cgp;
+
+ p = NSMakePoint (x, y);
+ cgp = QZ_PrivateSDLToCG (this, &p);
+
+ /* this is the magic call that fixes cursor "freezing" after warp */
+ CGAssociateMouseAndMouseCursorPosition (0);
+ CGWarpMouseCursorPosition (cgp);
+ if (grab_state != QZ_INVISIBLE_GRAB) { /* can't leave it disassociated? */
+ CGAssociateMouseAndMouseCursorPosition (1);
+ }
+ SDL_PrivateAppActive (QZ_IsMouseInWindow (this), SDL_APPMOUSEFOCUS);
+}
+
+void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
+
+ /* Only allow warping when in foreground */
+ if ( ! [ NSApp isActive ] )
+ return;
+
+ /* Do the actual warp */
+ if (grab_state != QZ_INVISIBLE_GRAB) QZ_PrivateWarpCursor (this, x, y);
+
+ /* Generate the mouse moved event */
+ SDL_PrivateMouseMotion (0, 0, x, y);
+}
+
+void QZ_MoveWMCursor (_THIS, int x, int y) { }
+void QZ_CheckMouseMode (_THIS) { }
+
+void QZ_SetCaption (_THIS, const char *title, const char *icon) {
+
+ if ( qz_window != nil ) {
+ NSString *string;
+ if ( title != NULL ) {
+ string = [ [ NSString alloc ] initWithUTF8String:title ];
+ [ qz_window setTitle:string ];
+ [ string release ];
+ }
+ if ( icon != NULL ) {
+ string = [ [ NSString alloc ] initWithUTF8String:icon ];
+ [ qz_window setMiniwindowTitle:string ];
+ [ string release ];
+ }
+ }
+}
+
+void QZ_SetWindowPos (_THIS, int x, int y)
+{
+ if ( qz_window == nil ) {
+ //printf( "%s(%d,%d): called for NULL window\n", __FUNCTION__, x, y );
+ return;
+ }
+
+ [ qz_window setFrameTopLeftPoint:NSMakePoint( x, this->hidden->height - y ) ];
+ //printf( "%s(%d,%d): done\n", __FUNCTION__, x, y );
+}
+
+void QZ_GetWindowPos(_THIS, int *px, int *py)
+{
+ NSPoint pt;
+
+ *px = *py = 0;
+
+ if ( qz_window == NULL ) {
+ //printf( "%s: called on NULL window\n", __FUNCTION__ );
+ }
+
+ if ( qz_window != nil ) {
+ NSRect rect = [ qz_window frame ];
+ *px = rect.origin.x;
+ *py = this->hidden->height - rect.origin.y - rect.size.height;
+ //printf( "%s: returning (%d,%d)\n", __FUNCTION__, *px, *py );
+ }
+}
+
+/* determine if the window is fully visible on the current screen configuration */
+int QZ_IsWindowVisible(_THIS, int recenter)
+{
+ int result = 0;
+
+ //printf( "... enter %s\n", __FUNCTION__ );
+
+ if ( qz_window != NULL ) {
+ NSRect frame = [ qz_window frame ];
+ NSArray* screens = [ NSScreen screens ];
+ unsigned int count = [ screens count ];
+ unsigned int n;
+ //printf( "window frame (%d,%d) (%d,%d)\n", frame.origin.x, frame.origin.y,
+ // frame.size.width, frame.size.height );
+ for (n = 0; n < count; n++) {
+ NSScreen* screen = [ screens objectAtIndex: n ];
+ NSRect vis = [ screen visibleFrame ];
+
+ //printf( "screen %d/%d frame (%d,%d) (%d,%d)\n", n+1, count,
+ // vis.origin.x, vis.origin.y, vis.size.width, vis.size.height );
+
+ if (frame.origin.x >= vis.origin.x &&
+ frame.origin.x + frame.size.width <= vis.origin.x + vis.size.width &&
+ frame.origin.y >= vis.origin.y &&
+ frame.origin.y + frame.size.height <= vis.origin.y + vis.size.height )
+ {
+ result = 1;
+ break;
+ }
+ }
+ }
+ //printf ( "... exit %s, result = %d\n", __FUNCTION__, result );
+ if ( !result && recenter ) {
+ [ qz_window center ] ;
+ }
+ return result;
+}
+
+int QZ_GetMonitorDPI(_THIS, int *xDpi, int *yDpi)
+{
+ /* FIXME: how to get this information from Cocoa ? */
+ return -1;
+}
+
+int QZ_GetMonitorRect (_THIS, SDL_Rect *rect)
+{
+ NSWindow* window = qz_window;
+ NSRect frame = [ window frame ];
+ int fx1 = frame.origin.x;
+ int fy1 = frame.origin.y;
+ int fx2 = frame.size.width + fx1;
+ int fy2 = frame.size.height + fy1;
+ NSArray* screens = [ NSScreen screens ];
+ unsigned int count = [ screens count ];
+ int bestScreen = -1;
+ int bestArea = 0;
+
+ unsigned int n;
+
+ /* we need to compute which screen has the most window pixels */
+ for (n = 0; n < count; n++) {
+ NSScreen* screen = [ screens objectAtIndex: n ];
+ NSRect vis = [ screen visibleFrame ];
+ int vx1 = vis.origin.x;
+ int vy1 = vis.origin.y;
+ int vx2 = vis.size.width + vx1;
+ int vy2 = vis.size.height + vy1;
+ int cx1, cx2, cy1, cy2, cArea;
+
+ if (fx1 >= vx2 || vx1 >= fx2 || fy1 >= vy2 || vy1 >= fy2)
+ continue;
+
+ cx1 = (fx1 < vx1) ? vx1 : fx1;
+ cx2 = (fx2 > vx2) ? vx2 : fx2;
+ cy1 = (fy1 < vy1) ? vy1 : fy1;
+ cy2 = (fy2 > vy2) ? vy2 : fy2;
+
+ if (cx1 >= cx2 || cy1 >= cy2)
+ continue;
+
+ cArea = (cx2-cx1)*(cy2-cy1);
+
+ if (bestScreen < 0 || cArea > bestArea) {
+ bestScreen = n;
+ bestArea = cArea;
+ }
+ }
+ if (bestScreen < 0)
+ bestScreen = 0;
+
+ {
+ NSScreen* screen = [ screens objectAtIndex: bestScreen ];
+ NSRect vis = [ screen visibleFrame ];
+
+ rect->x = vis.origin.x;
+ rect->y = vis.origin.y;
+ rect->w = vis.size.width;
+ rect->h = vis.size.height;
+ }
+ return 0;
+}
+
+void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
+{
+ NSBitmapImageRep *imgrep;
+ NSImage *img;
+ SDL_Surface *mergedSurface;
+ NSAutoreleasePool *pool;
+ Uint8 *pixels;
+ SDL_bool iconSrcAlpha;
+ Uint8 iconAlphaValue;
+ int i, j, maskPitch, index;
+
+ pool = [ [ NSAutoreleasePool alloc ] init ];
+
+ imgrep = [ [ [ NSBitmapImageRep alloc ] initWithBitmapDataPlanes: NULL pixelsWide: icon->w pixelsHigh: icon->h bitsPerSample: 8 samplesPerPixel: 4 hasAlpha: YES isPlanar: NO colorSpaceName: NSDeviceRGBColorSpace bytesPerRow: 4*icon->w bitsPerPixel: 32 ] autorelease ];
+ if (imgrep == nil) goto freePool;
+ pixels = [ imgrep bitmapData ];
+ SDL_memset(pixels, 0, 4*icon->w*icon->h); /* make the background, which will survive in colorkeyed areas, completely transparent */
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define BYTEORDER_DEPENDENT_RGBA_MASKS 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
+#else
+#define BYTEORDER_DEPENDENT_RGBA_MASKS 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
+#endif
+ mergedSurface = SDL_CreateRGBSurfaceFrom(pixels, icon->w, icon->h, 32, 4*icon->w, BYTEORDER_DEPENDENT_RGBA_MASKS);
+ if (mergedSurface == NULL) goto freePool;
+
+ /* blit, with temporarily cleared SRCALPHA flag because we want to copy, not alpha-blend */
+ iconSrcAlpha = ((icon->flags & SDL_SRCALPHA) != 0);
+ iconAlphaValue = icon->format->alpha;
+ SDL_SetAlpha(icon, 0, 255);
+ SDL_BlitSurface(icon, NULL, mergedSurface, NULL);
+ if (iconSrcAlpha) SDL_SetAlpha(icon, SDL_SRCALPHA, iconAlphaValue);
+
+ SDL_FreeSurface(mergedSurface);
+
+ /* apply mask, source alpha, and premultiply color values by alpha */
+ maskPitch = (icon->w+7)/8;
+ for (i = 0; i < icon->h; i++) {
+ for (j = 0; j < icon->w; j++) {
+ index = i*4*icon->w + j*4;
+ if (!(mask[i*maskPitch + j/8] & (128 >> j%8))) {
+ pixels[index + 3] = 0;
+ }
+ else {
+ if (iconSrcAlpha) {
+ if (icon->format->Amask == 0) pixels[index + 3] = icon->format->alpha;
+ }
+ else {
+ pixels[index + 3] = 255;
+ }
+ }
+ if (pixels[index + 3] < 255) {
+ pixels[index + 0] = (Uint16)pixels[index + 0]*pixels[index + 3]/255;
+ pixels[index + 1] = (Uint16)pixels[index + 1]*pixels[index + 3]/255;
+ pixels[index + 2] = (Uint16)pixels[index + 2]*pixels[index + 3]/255;
+ }
+ }
+ }
+
+ img = [ [ [ NSImage alloc ] initWithSize: NSMakeSize(icon->w, icon->h) ] autorelease ];
+ if (img == nil) goto freePool;
+ [ img addRepresentation: imgrep ];
+ [ NSApp setApplicationIconImage:img ];
+
+freePool:
+ [ pool release ];
+}
+
+int QZ_IconifyWindow (_THIS) {
+
+ if ( ! [ qz_window isMiniaturized ] ) {
+ [ qz_window miniaturize:nil ];
+ if ( ! [ qz_window isMiniaturized ] ) {
+ SDL_SetError ("window iconification failed");
+ return 0;
+ }
+ return 1;
+ }
+ else {
+ SDL_SetError ("window already iconified");
+ return 0;
+ }
+}
+
+int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
+ info->nsWindowPtr = qz_window;
+ return 0;
+}
+
+void QZ_ChangeGrabState (_THIS, int action) {
+
+ /*
+ Figure out what the next state should be based on the action.
+ Ignore actions that can't change the current state.
+ */
+ if ( grab_state == QZ_UNGRABBED ) {
+ if ( action == QZ_ENABLE_GRAB ) {
+ if ( cursor_should_be_visible )
+ grab_state = QZ_VISIBLE_GRAB;
+ else
+ grab_state = QZ_INVISIBLE_GRAB;
+ }
+ }
+ else if ( grab_state == QZ_VISIBLE_GRAB ) {
+ if ( action == QZ_DISABLE_GRAB )
+ grab_state = QZ_UNGRABBED;
+ else if ( action == QZ_HIDECURSOR )
+ grab_state = QZ_INVISIBLE_GRAB;
+ }
+ else {
+ assert( grab_state == QZ_INVISIBLE_GRAB );
+
+ if ( action == QZ_DISABLE_GRAB )
+ grab_state = QZ_UNGRABBED;
+ else if ( action == QZ_SHOWCURSOR )
+ grab_state = QZ_VISIBLE_GRAB;
+ }
+
+ /* now apply the new state */
+ if (grab_state == QZ_UNGRABBED) {
+
+ CGAssociateMouseAndMouseCursorPosition (1);
+ }
+ else if (grab_state == QZ_VISIBLE_GRAB) {
+
+ CGAssociateMouseAndMouseCursorPosition (1);
+ }
+ else {
+ assert( grab_state == QZ_INVISIBLE_GRAB );
+
+ QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
+ CGAssociateMouseAndMouseCursorPosition (0);
+ }
+}
+
+SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
+
+ int doGrab = grab_mode & SDL_GRAB_ON;
+ /*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN;*/
+
+ if ( this->screen == NULL ) {
+ SDL_SetError ("QZ_GrabInput: screen is NULL");
+ return SDL_GRAB_OFF;
+ }
+
+ if ( ! video_set ) {
+ /*SDL_SetError ("QZ_GrabInput: video is not set, grab will take effect on mode switch"); */
+ current_grab_mode = grab_mode;
+ return grab_mode; /* Will be set later on mode switch */
+ }
+
+ if ( grab_mode != SDL_GRAB_QUERY ) {
+ if ( doGrab )
+ QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
+ else
+ QZ_ChangeGrabState (this, QZ_DISABLE_GRAB);
+
+ current_grab_mode = doGrab ? SDL_GRAB_ON : SDL_GRAB_OFF;
+ QZ_UpdateCursor(this);
+ }
+
+ return current_grab_mode;
+}
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.h
new file mode 100644
index 0000000..d19375b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.h
@@ -0,0 +1,51 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1050)
+typedef unsigned int NSUInteger;
+#endif
+
+/* Subclass of NSWindow to fix genie effect and support resize events */
+@interface SDL_QuartzWindow : NSWindow
+{
+ BOOL watchForMouseUp;
+}
+
+- (void)miniaturize:(id)sender;
+- (void)display;
+- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
+- (void)appDidHide:(NSNotification*)note;
+- (void)appWillUnhide:(NSNotification*)note;
+- (void)appDidUnhide:(NSNotification*)note;
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
+@end
+
+/* Delegate for our NSWindow to send SDLQuit() on close */
+@interface SDL_QuartzWindowDelegate : NSObject
+- (BOOL)windowShouldClose:(id)sender;
+@end
+
+/* Subclass of NSView to set cursor rectangle */
+@interface SDL_QuartzView : NSView
+- (void)resetCursorRects;
+@end
diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.m
new file mode 100644
index 0000000..375833f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWindow.m
@@ -0,0 +1,231 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWM.h"
+#include "SDL_QuartzWindow.h"
+
+/*
+ This function makes the *SDL region* of the window 100% opaque.
+ The genie effect uses the alpha component. Otherwise,
+ it doesn't seem to matter what value it has.
+*/
+static void QZ_SetPortAlphaOpaque () {
+
+ SDL_Surface *surface = current_video->screen;
+ int bpp;
+
+ bpp = surface->format->BitsPerPixel;
+
+ if (bpp == 32) {
+
+ Uint32 *pixels = (Uint32*) surface->pixels;
+ Uint32 rowPixels = surface->pitch / 4;
+ Uint32 i, j;
+
+ for (i = 0; i < surface->h; i++)
+ for (j = 0; j < surface->w; j++) {
+
+ pixels[ (i * rowPixels) + j ] |= 0xFF000000;
+ }
+ }
+}
+
+@implementation SDL_QuartzWindow
+
+/* we override these methods to fix the miniaturize animation/dock icon bug */
+- (void)miniaturize:(id)sender
+{
+ if (SDL_VideoSurface->flags & SDL_OPENGL) {
+
+ /*
+ Future: Grab framebuffer and put into NSImage
+ [ qz_window setMiniwindowImage:image ];
+ */
+ }
+ else {
+
+ /* make the alpha channel opaque so anim won't have holes in it */
+ QZ_SetPortAlphaOpaque ();
+ }
+
+ /* window is hidden now */
+ SDL_PrivateAppActive (0, SDL_APPACTIVE);
+
+ [ super miniaturize:sender ];
+}
+
+- (void)display
+{
+ /*
+ This method fires just before the window deminaturizes from the Dock.
+
+ We'll save the current visible surface, let the window manager redraw any
+ UI elements, and restore the SDL surface. This way, no expose event
+ is required, and the deminiaturize works perfectly.
+ */
+ SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+
+ /* make sure pixels are fully opaque */
+ if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
+ QZ_SetPortAlphaOpaque ();
+
+ /* save current visible SDL surface */
+ [ self cacheImageInRect:[ window_view frame ] ];
+
+ /* let the window manager redraw controls, border, etc */
+ [ super display ];
+
+ /* restore visible SDL surface */
+ [ self restoreCachedImage ];
+
+ /* window is visible again */
+ SDL_PrivateAppActive (1, SDL_APPACTIVE);
+}
+
+- (void)setFrame:(NSRect)frameRect display:(BOOL)flag
+{
+
+ /*
+ If the video surface is NULL, this originated from QZ_SetVideoMode,
+ so don't send the resize event.
+ */
+ SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+
+ if (this && SDL_VideoSurface == NULL) {
+
+ [ super setFrame:frameRect display:flag ];
+ }
+ else if (this && qz_window) {
+
+ NSRect newViewFrame;
+
+ [ super setFrame:frameRect display:flag ];
+
+ newViewFrame = [ window_view frame ];
+
+ SDL_PrivateResize (newViewFrame.size.width, newViewFrame.size.height);
+ }
+}
+
+/* QZ_DoActivate() calls a low-level CoreGraphics routine to adjust
+ the cursor position, if input is being grabbed. If app activation is
+ triggered by a mouse click in the title bar, then the window manager
+ gets confused and thinks we're dragging the window. The solution
+ below postpones the activate event to avoid this scenario. */
+- (void)becomeKeyWindow
+{
+ NSEvent *event = [self currentEvent];
+ if ([event type] == NSLeftMouseDown && [event window] == self)
+ watchForMouseUp = YES;
+ else
+ [super becomeKeyWindow];
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ [super sendEvent:event];
+ if (watchForMouseUp && [event type] == NSLeftMouseUp)
+ {
+ watchForMouseUp = NO;
+ [super becomeKeyWindow];
+ }
+}
+
+- (void)appDidHide:(NSNotification*)note
+{
+ SDL_PrivateAppActive (0, SDL_APPACTIVE);
+}
+
+- (void)appWillUnhide:(NSNotification*)note
+{
+ SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+
+ if ( this ) {
+
+ /* make sure pixels are fully opaque */
+ if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
+ QZ_SetPortAlphaOpaque ();
+
+ /* save current visible SDL surface */
+ [ self cacheImageInRect:[ window_view frame ] ];
+ }
+}
+
+- (void)appDidUnhide:(NSNotification*)note
+{
+ /* restore cached image, since it may not be current, post expose event too */
+ [ self restoreCachedImage ];
+
+ /*SDL_PrivateExpose ();*/
+
+ SDL_PrivateAppActive (1, SDL_APPACTIVE);
+}
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
+{
+ /* Make our window subclass receive these application notifications */
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appDidHide:) name:NSApplicationDidHideNotification object:NSApp ];
+
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
+
+ [ [ NSNotificationCenter defaultCenter ] addObserver:self
+ selector:@selector(appWillUnhide:) name:NSApplicationWillUnhideNotification object:NSApp ];
+
+ return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
+}
+
+@end
+
+@implementation SDL_QuartzWindowDelegate
+- (BOOL)windowShouldClose:(id)sender
+{
+ SDL_PrivateQuit();
+ return NO;
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)aNotification
+{
+ QZ_DoActivate (current_video);
+}
+
+- (void)windowDidResignKey:(NSNotification *)aNotification
+{
+ QZ_DoDeactivate (current_video);
+}
+
+@end
+
+@implementation SDL_QuartzView
+
+- (void)resetCursorRects
+{
+ SDL_Cursor *sdlc = SDL_GetCursor();
+ if (sdlc != NULL && sdlc->wm_cursor != NULL) {
+ [self addCursorRect: [self visibleRect] cursor: sdlc->wm_cursor->nscursor];
+ }
+}
+
+@end
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S
new file mode 100644
index 0000000..fae32f8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosASM.S
@@ -0,0 +1,116 @@
+;
+; SDL - Simple DirectMedia Layer
+; Copyright (C) 1997-2012 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
+;
+; Assembler routines for RISC OS display
+;
+
+ AREA |C$$CODE|
+
+ EXPORT |RISCOS_Put32|
+
+; Display 32bpp to 32bpp, 1:1
+;
+; Code provided by Adrain Lees
+;
+; entry a1 -> destination
+; a2 = dest width in pixels
+; a3 = dest line length in bytes
+; a4 = dest height in scanlines
+; arg5 -> source
+; arg6 = byte offset from end of source line to start of next
+
+Arg5 * 10*4
+Arg6 * Arg5+4
+
+RISCOS_Put32 ROUT
+ STMFD sp!,{a2,v1-v6,sl,fp,lr}
+ LDR ip,[sp,#Arg5]
+ MOV lr,a1
+ B ucp64lp
+
+00 ;tail strip of 1-15 pixels
+
+ LDR v1,[ip],#4
+01 SUBS a2,a2,#1
+ STR v1,[lr],#4
+ LDRHI v1,[ip],#4
+ BHI %01
+ B %02
+
+ucp64end ADDS a2,a2,#16
+ BNE %00
+
+02 SUBS a4,a4,#1 ;height--
+ LDRHI v1,[sp,#Arg6]
+ LDRHI a2,[sp] ;reload width
+ BLS %03
+
+ ;move to start of next scanline
+
+ ADD lr,a1,a3
+ ADD a1,a1,a3
+ ADD ip,ip,v1
+
+ucp64lp SUBS a2,a2,#16
+ BLO ucp64end
+
+ PLD [ip,#64]
+
+ LDR v1,[ip],#4
+ LDR v2,[ip],#4
+ LDR v3,[ip],#4
+ LDR v4,[ip],#4
+ LDR v5,[ip],#4
+ LDR v6,[ip],#4
+ LDR sl,[ip],#4
+ LDR fp,[ip],#4
+ STR v1,[lr],#4
+ STR v2,[lr],#4
+ STR v3,[lr],#4
+ STR v4,[lr],#4
+ STR v5,[lr],#4
+ STR v6,[lr],#4
+ STR sl,[lr],#4
+ STR fp,[lr],#4
+
+ PLD [ip,#64]
+
+ LDR v1,[ip],#4
+ LDR v2,[ip],#4
+ LDR v3,[ip],#4
+ LDR v4,[ip],#4
+ LDR v5,[ip],#4
+ LDR v6,[ip],#4
+ LDR sl,[ip],#4
+ LDR fp,[ip],#4
+ STR v1,[lr],#4
+ STR v2,[lr],#4
+ STR v3,[lr],#4
+ STR v4,[lr],#4
+ STR v5,[lr],#4
+ STR v6,[lr],#4
+ STR sl,[lr],#4
+ STR fp,[lr],#4
+
+ B ucp64lp
+
+03 LDMFD sp!,{a2,v1-v6,sl,fp,pc}
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c
new file mode 100644
index 0000000..b8c3cf7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosFullScreenVideo.c
@@ -0,0 +1,777 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements RISC OS full screen display.
+*/
+
+#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_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+#include "unixlib/os.h"
+#include "unixlib/local.h"
+
+/* Private structures */
+typedef struct tagScreenModeBlock
+{
+ int flags; // mode selector flags, bit 0 = 1, bit 1-7 format specifier, 8-31 reserved
+ int x_pixels;
+ int y_pixels;
+ int pixel_depth; // 2^pixel_depth = bpp,i.e. 0 = 1, 1 = 2, 4 = 16, 5 = 32
+ int frame_rate; // -1 use first match
+ int mode_vars[5]; // array of index, value pairs terminated by -1
+} SCREENMODEBLOCK;
+
+
+/* Helper functions */
+void FULLSCREEN_SetDeviceMode(_THIS);
+int FULLSCREEN_SetMode(int width, int height, int bpp);
+void FULLSCREEN_SetupBanks(_THIS);
+
+/* SDL video device functions for fullscreen mode */
+static int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface);
+void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon);
+extern int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
+
+/* UpdateRects variants */
+static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects);
+static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects);
+
+/* Local helper functions */
+static int cmpmodes(const void *va, const void *vb);
+static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h);
+void FULLSCREEN_SetWriteBank(int bank);
+void FULLSCREEN_SetDisplayBank(int bank);
+static void FULLSCREEN_DisableEscape();
+static void FULLSCREEN_EnableEscape();
+void FULLSCREEN_BuildModeList(_THIS);
+
+/* Following variable is set up in riskosTask.c */
+extern int riscos_backbuffer; /* Create a back buffer in system memory for full screen mode */
+
+/* Following is used to create a sprite back buffer */
+extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
+
+/* Fast assembler copy */
+extern void RISCOS_Put32(void *to, int pixels, int pitch, int rows, void *from, int src_skip_bytes);
+
+SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ _kernel_swi_regs regs;
+ Uint32 Rmask = 0;
+ Uint32 Gmask = 0;
+ Uint32 Bmask = 0;
+ int create_back_buffer = riscos_backbuffer;
+
+ switch(bpp)
+ {
+ case 8:
+ flags |= SDL_HWPALETTE;
+ break;
+
+ case 15:
+ case 16:
+ Bmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Rmask = 0x0000001f;
+ break;
+
+ case 32:
+ Bmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Rmask = 0x000000ff;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return NULL;
+ break;
+ }
+
+ if (FULLSCREEN_SetMode(width, height, bpp) == 0)
+ {
+ SDL_SetError("Couldn't set requested mode");
+ return (NULL);
+ }
+
+/* printf("Setting mode %dx%d\n", width, height); */
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
+ RISCOS_RestoreWimpMode();
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->w = width;
+ this->hidden->height = current->h = height;
+
+ regs.r[0] = -1; /* -1 for current screen mode */
+
+ /* Get screen width in bytes */
+ regs.r[1] = 6; // Screen Width in bytes
+ _kernel_swi(OS_ReadModeVariable, &regs, &regs);
+
+ current->pitch = regs.r[2];
+
+ if (flags & SDL_DOUBLEBUF)
+ {
+ regs.r[0] = 2; /* Screen area */
+ _kernel_swi(OS_ReadDynamicArea, &regs, &regs);
+
+ /* Reg 1 has amount of memory currently used for display */
+ regs.r[0] = 2; /* Screen area */
+ regs.r[1] = (current->pitch * height * 2) - regs.r[1];
+ if (_kernel_swi(OS_ChangeDynamicArea, &regs, &regs) != NULL)
+ {
+ /* Can't allocate enough screen memory for double buffer */
+ flags &= ~SDL_DOUBLEBUF;
+ }
+ }
+
+ current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC;
+
+
+ /* Need to set display banks here for double buffering */
+ if (flags & SDL_DOUBLEBUF)
+ {
+ FULLSCREEN_SetWriteBank(0);
+ FULLSCREEN_SetDisplayBank(1);
+
+ create_back_buffer = 0; /* Don't need a back buffer for a double buffered display */
+ }
+
+ FULLSCREEN_SetupBanks(this);
+
+ if (create_back_buffer)
+ {
+ /* If not double buffered we may need to create a memory
+ ** back buffer to simulate processing on other OSes.
+ ** This is turned on by setting the enviromental variable
+ ** SDL$<name>$BackBuffer >= 1
+ */
+ if (riscos_backbuffer == 3)
+ this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp);
+ else
+ this->hidden->bank[0] = SDL_malloc(height * current->pitch);
+ if (this->hidden->bank[0] == 0)
+ {
+ RISCOS_RestoreWimpMode();
+ SDL_SetError("Couldnt allocate memory for back buffer");
+ return (NULL);
+ }
+ /* Surface updated in programs is now a software surface */
+ current->flags &= ~SDL_HWSURFACE;
+ }
+
+ /* Store address of allocated screen bank to be freed later */
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ if (create_back_buffer)
+ {
+ this->hidden->alloc_bank = this->hidden->bank[0];
+ if (riscos_backbuffer == 3)
+ {
+ this->hidden->bank[0] += 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+ }
+ } else
+ this->hidden->alloc_bank = 0;
+
+ // Clear both banks to black
+ SDL_memset(this->hidden->bank[0], 0, height * current->pitch);
+ SDL_memset(this->hidden->bank[1], 0, height * current->pitch);
+
+ this->hidden->current_bank = 0;
+ current->pixels = this->hidden->bank[0];
+
+ /* Have to set the screen here, so SetDeviceMode will pick it up */
+ this->screen = current;
+
+ /* Reset device functions for the wimp */
+ FULLSCREEN_SetDeviceMode(this);
+
+/* FULLSCREEN_DisableEscape(); */
+
+ /* We're done */
+ return(current);
+}
+
+/* Reset any device functions that have been changed because we have run in WIMP mode */
+void FULLSCREEN_SetDeviceMode(_THIS)
+{
+ /* Update rects is different if we have a backbuffer */
+
+ if (riscos_backbuffer && (this->screen->flags & SDL_DOUBLEBUF) == 0)
+ {
+ switch(riscos_backbuffer)
+ {
+ case 2: /* ARM code full word copy */
+ switch(this->screen->format->BytesPerPixel)
+ {
+ case 1: /* 8bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects8bpp;
+ break;
+ case 2: /* 15/16bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects16bpp;
+ break;
+ case 4: /* 32 bpp modes */
+ this->UpdateRects = FULLSCREEN_UpdateRects32bpp;
+ break;
+
+ default: /* Just default to the memcpy routine */
+ this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy;
+ break;
+ }
+ break;
+
+ case 3: /* Use OS sprite plot routine */
+ this->UpdateRects = FULLSCREEN_UpdateRectsOS;
+ break;
+
+ default: /* Old but safe memcpy */
+ this->UpdateRects = FULLSCREEN_UpdateRectsMemCpy;
+ break;
+ }
+ } else
+ this->UpdateRects = FULLSCREEN_UpdateRects; /* Default do nothing implementation */
+
+ this->SetColors = FULLSCREEN_SetColors;
+
+ this->FlipHWSurface = FULLSCREEN_FlipHWSurface;
+
+ this->SetCaption = FULLSCREEN_SetWMCaption;
+ this->SetIcon = NULL;
+ this->IconifyWindow = NULL;
+
+ this->ShowWMCursor = RISCOS_ShowWMCursor;
+ this->WarpWMCursor = FULLSCREEN_WarpWMCursor;
+
+ this->PumpEvents = FULLSCREEN_PumpEvents;
+}
+
+/* Query for the list of available video modes */
+void FULLSCREEN_BuildModeList(_THIS)
+{
+ _kernel_swi_regs regs;
+ char *enumInfo = NULL;
+ char *enum_ptr;
+ int *blockInfo;
+ int j;
+ int num_modes;
+
+ /* Find out how much space we need */
+ regs.r[0] = 2; /* Reason code */
+ regs.r[2] = 0; /* Number of modes to skip */
+ regs.r[6] = 0; /* pointer to block or 0 for count */
+ regs.r[7] = 0; /* Size of block in bytes */
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+
+ num_modes = -regs.r[2];
+
+ /* Video memory should be in r[5] */
+ this->info.video_mem = regs.r[5]/1024;
+
+ enumInfo = (unsigned char *)SDL_malloc(-regs.r[7]);
+ if (enumInfo == NULL)
+ {
+ SDL_OutOfMemory();
+ return;
+ }
+ /* Read mode information into block */
+ regs.r[2] = 0;
+ regs.r[6] = (int)enumInfo;
+ regs.r[7] = -regs.r[7];
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+
+ enum_ptr = enumInfo;
+
+ for (j =0; j < num_modes;j++)
+ {
+ blockInfo = (int *)enum_ptr;
+ if ((blockInfo[1] & 255) == 1) /* We understand this format */
+ {
+ switch(blockInfo[4])
+ {
+ case 3: /* 8 bits per pixel */
+ FULLSCREEN_AddMode(this, 8, blockInfo[2], blockInfo[3]);
+ break;
+ case 4: /* 15 bits per pixel */
+ FULLSCREEN_AddMode(this, 15, blockInfo[2], blockInfo[3]);
+ break;
+ case 5: /* 32 bits per pixel */
+ FULLSCREEN_AddMode(this, 32, blockInfo[2], blockInfo[3]);
+ break;
+ }
+ }
+
+ enum_ptr += blockInfo[0];
+ }
+
+ SDL_free(enumInfo);
+
+ /* Sort the mode lists */
+ for ( j=0; j<NUM_MODELISTS; ++j ) {
+ if ( SDL_nummodes[j] > 0 ) {
+ SDL_qsort(SDL_modelist[j], SDL_nummodes[j], sizeof *SDL_modelist[j], cmpmodes);
+ }
+ }
+}
+
+static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 19;
+
+ FULLSCREEN_SetDisplayBank(this->hidden->current_bank);
+ this->hidden->current_bank ^= 1;
+ FULLSCREEN_SetWriteBank(this->hidden->current_bank);
+ surface->pixels = this->hidden->bank[this->hidden->current_bank];
+
+ /* Wait for Vsync */
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+ return(0);
+}
+
+/* Nothing to do if we are writing direct to hardware */
+static void FULLSCREEN_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+}
+
+/* Safe but slower Memory copy from our allocated back buffer */
+static void FULLSCREEN_UpdateRectsMemCpy(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int row;
+ int xmult = this->screen->format->BytesPerPixel;
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + rects->x * xmult + rects->y * pitch;
+ to = this->hidden->bank[1] + rects->x * xmult + rects->y * pitch;
+ for (row = 0; row < rects->h; row++)
+ {
+ SDL_memcpy(to, from, rects->w * xmult);
+ from += pitch;
+ to += pitch;
+ }
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. Deliberately copies extra columns if
+ necessary to ensure the rectangle is word aligned. */
+static void FULLSCREEN_UpdateRects8bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width_bytes;
+ int src_skip_bytes;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + rects->x + rects->y * pitch;
+ to = this->hidden->bank[1] + rects->x + rects->y * pitch;
+ width_bytes = rects->w;
+ if ((int)from & 3)
+ {
+ int extra = ((int)from & 3);
+ from -= extra;
+ to -= extra;
+ width_bytes += extra;
+ }
+ if (width_bytes & 3) width_bytes += 4 - (width_bytes & 3);
+ src_skip_bytes = pitch - width_bytes;
+
+ RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes);
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. Deliberately copies extra columns if
+ necessary to ensure the rectangle is word aligned. */
+static void FULLSCREEN_UpdateRects16bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width_bytes;
+ int src_skip_bytes;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + (rects->x << 1) + rects->y * pitch;
+ to = this->hidden->bank[1] + (rects->x << 1) + rects->y * pitch;
+ width_bytes = (((int)rects->w) << 1);
+ if ((int)from & 3)
+ {
+ from -= 2;
+ to -= 2;
+ width_bytes += 2;
+ }
+ if (width_bytes & 3) width_bytes += 2;
+ src_skip_bytes = pitch - width_bytes;
+
+ RISCOS_Put32(to, (width_bytes >> 2), pitch, (int)rects->h, from, src_skip_bytes);
+ rects++;
+ }
+}
+
+/* Use optimized assembler memory copy. 32 bpp modes are always word aligned */
+static void FULLSCREEN_UpdateRects32bpp(_THIS, int numrects, SDL_Rect *rects)
+{
+ int j;
+ char *to, *from;
+ int pitch = this->screen->pitch;
+ int width;
+
+ for (j = 0; j < numrects; j++)
+ {
+ from = this->hidden->bank[0] + (rects->x << 2) + rects->y * pitch;
+ to = this->hidden->bank[1] + (rects->x << 2) + rects->y * pitch;
+ width = (int)rects->w ;
+
+ RISCOS_Put32(to, width, pitch, (int)rects->h, from, pitch - (width << 2));
+ rects++;
+ }
+}
+
+/* Use operating system sprite plots. Currently this is much slower than the
+ other variants however accelerated sprite plotting can be seen on the horizon
+ so this prepares for it. */
+static void FULLSCREEN_UpdateRectsOS(_THIS, int numrects, SDL_Rect *rects)
+{
+ _kernel_swi_regs regs;
+ _kernel_oserror *err;
+ int j;
+ int y;
+
+ regs.r[0] = 28 + 512;
+ regs.r[1] = (unsigned int)this->hidden->alloc_bank;
+ regs.r[2] = (unsigned int)this->hidden->alloc_bank+16;
+ regs.r[5] = 0;
+
+ for (j = 0; j < numrects; j++)
+ {
+ y = this->screen->h - rects->y; /* top of clipping region */
+ _kernel_oswrch(24); /* Set graphics clip region */
+ _kernel_oswrch((rects->x << this->hidden->xeig) & 0xFF); /* left */
+ _kernel_oswrch(((rects->x << this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((y - rects->h) << this->hidden->yeig) & 0xFF); /* bottom */
+ _kernel_oswrch((((y - rects->h) << this->hidden->yeig)>> 8) & 0xFF);
+ _kernel_oswrch(((rects->x + rects->w - 1) << this->hidden->xeig) & 0xFF); /* right */
+ _kernel_oswrch((((rects->x + rects->w - 1)<< this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((y-1) << this->hidden->yeig) & 0xFF); /* top */
+ _kernel_oswrch((((y-1) << this->hidden->yeig) >> 8) & 0xFF);
+
+ regs.r[3] = 0;
+ regs.r[4] = 0;
+
+ if ((err = _kernel_swi(OS_SpriteOp, &regs, &regs)) != 0)
+ {
+ printf("OS_SpriteOp failed \n%s\n",err->errmess);
+ }
+
+ rects++;
+
+ /* Reset to full screen clipping */
+ _kernel_oswrch(24); /* Set graphics clip region */
+ _kernel_oswrch(0); /* left */
+ _kernel_oswrch(0);
+ _kernel_oswrch(0); /* bottom */
+ _kernel_oswrch(0);
+ _kernel_oswrch(((this->screen->w-1) << this->hidden->xeig) & 0xFF); /* right */
+ _kernel_oswrch((((this->screen->w-1) << this->hidden->xeig) >> 8) & 0xFF);
+ _kernel_oswrch(((this->screen->h-1) << this->hidden->yeig) & 0xFF); /* top */
+ _kernel_oswrch((((this->screen->h-1) << this->hidden->yeig) >> 8) & 0xFF);
+ }
+}
+
+
+int FULLSCREEN_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ _kernel_swi_regs regs;
+ int palette[256];
+
+ regs.r[0] = -1;
+ regs.r[1] = -1;
+ regs.r[2] = (int)palette;
+ regs.r[3] = 1024;
+ regs.r[4] = 0;
+ _kernel_swi(ColourTrans_ReadPalette, &regs, &regs);
+
+ while(ncolors--)
+ {
+ palette[firstcolor] = ((colors->b) << 24) | ((colors->g) << 16) | ((colors->r) << 8);
+ firstcolor++;
+ colors++;
+ }
+
+ regs.r[0] = -1;
+ regs.r[1] = -1;
+ regs.r[2] = (int)palette;
+ regs.r[3] = 0;
+ regs.r[4] = 0;
+ _kernel_swi(ColourTrans_WritePalette, &regs, &regs);
+
+ return(1);
+}
+
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ SDL_Rect *a = *(SDL_Rect **)va;
+ SDL_Rect *b = *(SDL_Rect **)vb;
+ if(a->w == b->w)
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+
+static int FULLSCREEN_AddMode(_THIS, int bpp, int w, int h)
+{
+ SDL_Rect *mode;
+ int i, index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( bpp < 8 ) { /* Not supported */
+ return(0);
+ }
+ index = ((bpp+7)/8)-1;
+ for ( i=0; i<SDL_nummodes[index]; ++i ) {
+ mode = SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+void FULLSCREEN_SetWriteBank(int bank)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 112;
+ regs.r[1] = bank+1;
+ _kernel_swi(OS_Byte, &regs, &regs);
+}
+
+void FULLSCREEN_SetDisplayBank(int bank)
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 113;
+ regs.r[1] = bank+1;
+ _kernel_swi(OS_Byte, &regs, &regs);
+}
+
+
+/** Disable special escape key processing */
+static void FULLSCREEN_DisableEscape()
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 229;
+ regs.r[1] = 1;
+ regs.r[2] = 0;
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+}
+
+/** Enable special escape key processing */
+static void FULLSCREEN_EnableEscape()
+{
+ _kernel_swi_regs regs;
+ regs.r[0] = 229;
+ regs.r[1] = 0;
+ regs.r[2] = 0;
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+}
+
+/** Store caption in case this is called before we create a window */
+void FULLSCREEN_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title));
+}
+
+/* Set screen mode
+*
+* Returns 1 if mode is set ok, otherwise 0
+*/
+
+int FULLSCREEN_SetMode(int width, int height, int bpp)
+{
+ SCREENMODEBLOCK smb;
+ _kernel_swi_regs regs;
+
+ smb.flags = 1;
+ smb.x_pixels = width;
+ smb.y_pixels = height;
+ smb.mode_vars[0] = -1;
+
+ switch(bpp)
+ {
+ case 8:
+ smb.pixel_depth = 3;
+ /* Note: Need to set ModeFlags to 128 and NColour variables to 255 get full 8 bit palette */
+ smb.mode_vars[0] = 0; smb.mode_vars[1] = 128; /* Mode flags */
+ smb.mode_vars[2] = 3; smb.mode_vars[3] = 255; /* NColour (number of colours -1) */
+ smb.mode_vars[4] = -1; /* End of list */
+ break;
+
+ case 15:
+ case 16:
+ smb.pixel_depth = 4;
+ break;
+
+ case 32:
+ smb.pixel_depth = 5;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return 0;
+ break;
+ }
+
+ smb.frame_rate = -1;
+
+ regs.r[0] = 0;
+ regs.r[1] = (int)&smb;
+
+ if (_kernel_swi(OS_ScreenMode, &regs, &regs) != 0)
+ {
+ SDL_SetError("Couldn't set requested mode");
+ return 0;
+ }
+
+ /* Turn cursor off*/
+ _kernel_oswrch(23);_kernel_oswrch(1);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);_kernel_oswrch(0);
+ _kernel_oswrch(0);_kernel_oswrch(0);
+
+ return 1;
+}
+
+/* Get Start addresses for the screen banks */
+void FULLSCREEN_SetupBanks(_THIS)
+{
+ _kernel_swi_regs regs;
+ int block[5];
+ block[0] = 148; /* Write screen start */
+ block[1] = 149; /* Display screen start */
+ block[2] = 4; /* X eig factor */
+ block[3] = 5; /* Y eig factor */
+ block[4] = -1; /* End of list of variables to request */
+
+ regs.r[0] = (int)block;
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+
+ this->hidden->bank[0] = (void *)block[0];
+ this->hidden->bank[1] = (void *)block[1];
+ this->hidden->xeig = block[2];
+ this->hidden->yeig = block[3];
+}
+
+/* Toggle to full screen mode from the WIMP */
+
+int FULLSCREEN_ToggleFromWimp(_THIS)
+{
+ int width = this->screen->w;
+ int height = this->screen->h;
+ int bpp = this->screen->format->BitsPerPixel;
+
+ RISCOS_StoreWimpMode();
+ if (FULLSCREEN_SetMode(width, height, bpp))
+ {
+ char *buffer = this->hidden->alloc_bank; /* This is start of sprite data */
+ /* Support back buffer mode only */
+ if (riscos_backbuffer == 0) riscos_backbuffer = 1;
+
+ FULLSCREEN_SetupBanks(this);
+
+ this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->current_bank = 0;
+ this->screen->pixels = this->hidden->bank[0];
+
+ /* Copy back buffer to screen memory */
+ SDL_memcpy(this->hidden->bank[1], this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
+
+ FULLSCREEN_SetDeviceMode(this);
+ return 1;
+ } else
+ RISCOS_RestoreWimpMode();
+
+ return 0;
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c
new file mode 100644
index 0000000..5487507
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents.c
@@ -0,0 +1,549 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements keyboard setup, event pump and keyboard and mouse polling
+*/
+
+
+#include "SDL.h"
+#include "../../timer/SDL_timer_c.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+
+#include "memory.h"
+#include "stdlib.h"
+#include "ctype.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+/* The translation table from a RISC OS internal key numbers to a SDL keysym */
+static SDLKey RO_keymap[SDLK_LAST];
+
+/* RISC OS Key codes */
+#define ROKEY_SHIFT 0
+#define ROKEY_CTRL 1
+#define ROKEY_ALT 2
+/* Left shift is first key we will check for */
+#define ROKEY_LEFT_SHIFT 3
+
+/* Need to ignore mouse buttons as they are processed separately */
+#define ROKEY_LEFT_MOUSE 9
+#define ROKEY_CENTRE_MOUSE 10
+#define ROKEY_RIGHT_MOUSE 11
+
+/* No key has been pressed return value*/
+#define ROKEY_NONE 255
+
+/* Id of last key in keyboard */
+#define ROKEY_LAST_KEY 124
+
+/* Size of array for all keys */
+#define ROKEYBD_ARRAYSIZE 125
+
+static char RO_pressed[ROKEYBD_ARRAYSIZE];
+
+static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed);
+
+void RISCOS_PollMouse(_THIS);
+void RISCOS_PollKeyboard();
+
+void RISCOS_PollMouseHelper(_THIS, int fullscreen);
+
+#if SDL_THREADS_DISABLED
+extern void DRenderer_FillBuffers();
+
+/* Timer running function */
+extern void RISCOS_CheckTimer();
+
+#endif
+
+void FULLSCREEN_PumpEvents(_THIS)
+{
+ /* Current implementation requires keyboard and mouse polling */
+ RISCOS_PollKeyboard();
+ RISCOS_PollMouse(this);
+#if SDL_THREADS_DISABLED
+// DRenderer_FillBuffers();
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
+
+
+void RISCOS_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Map the VK keysyms */
+ for ( i=0; i<SDL_arraysize(RO_keymap); ++i )
+ RO_keymap[i] = SDLK_UNKNOWN;
+
+ RO_keymap[3] = SDLK_LSHIFT;
+ RO_keymap[4] = SDLK_LCTRL;
+ RO_keymap[5] = SDLK_LALT;
+ RO_keymap[6] = SDLK_RSHIFT;
+ RO_keymap[7] = SDLK_RCTRL;
+ RO_keymap[8] = SDLK_RALT;
+ RO_keymap[16] = SDLK_q;
+ RO_keymap[17] = SDLK_3;
+ RO_keymap[18] = SDLK_4;
+ RO_keymap[19] = SDLK_5;
+ RO_keymap[20] = SDLK_F4;
+ RO_keymap[21] = SDLK_8;
+ RO_keymap[22] = SDLK_F7;
+ RO_keymap[23] = SDLK_MINUS,
+ RO_keymap[25] = SDLK_LEFT;
+ RO_keymap[26] = SDLK_KP6;
+ RO_keymap[27] = SDLK_KP7;
+ RO_keymap[28] = SDLK_F11;
+ RO_keymap[29] = SDLK_F12;
+ RO_keymap[30] = SDLK_F10;
+ RO_keymap[31] = SDLK_SCROLLOCK;
+ RO_keymap[32] = SDLK_PRINT;
+ RO_keymap[33] = SDLK_w;
+ RO_keymap[34] = SDLK_e;
+ RO_keymap[35] = SDLK_t;
+ RO_keymap[36] = SDLK_7;
+ RO_keymap[37] = SDLK_i;
+ RO_keymap[38] = SDLK_9;
+ RO_keymap[39] = SDLK_0;
+ RO_keymap[41] = SDLK_DOWN;
+ RO_keymap[42] = SDLK_KP8;
+ RO_keymap[43] = SDLK_KP9;
+ RO_keymap[44] = SDLK_BREAK;
+ RO_keymap[45] = SDLK_BACKQUOTE;
+/* RO_keymap[46] = SDLK_currency; TODO: Figure out if this has a value */
+ RO_keymap[47] = SDLK_BACKSPACE;
+ RO_keymap[48] = SDLK_1;
+ RO_keymap[49] = SDLK_2;
+ RO_keymap[50] = SDLK_d;
+ RO_keymap[51] = SDLK_r;
+ RO_keymap[52] = SDLK_6;
+ RO_keymap[53] = SDLK_u;
+ RO_keymap[54] = SDLK_o;
+ RO_keymap[55] = SDLK_p;
+ RO_keymap[56] = SDLK_LEFTBRACKET;
+ RO_keymap[57] = SDLK_UP;
+ RO_keymap[58] = SDLK_KP_PLUS;
+ RO_keymap[59] = SDLK_KP_MINUS;
+ RO_keymap[60] = SDLK_KP_ENTER;
+ RO_keymap[61] = SDLK_INSERT;
+ RO_keymap[62] = SDLK_HOME;
+ RO_keymap[63] = SDLK_PAGEUP;
+ RO_keymap[64] = SDLK_CAPSLOCK;
+ RO_keymap[65] = SDLK_a;
+ RO_keymap[66] = SDLK_x;
+ RO_keymap[67] = SDLK_f;
+ RO_keymap[68] = SDLK_y;
+ RO_keymap[69] = SDLK_j;
+ RO_keymap[70] = SDLK_k;
+ RO_keymap[72] = SDLK_SEMICOLON;
+ RO_keymap[73] = SDLK_RETURN;
+ RO_keymap[74] = SDLK_KP_DIVIDE;
+ RO_keymap[76] = SDLK_KP_PERIOD;
+ RO_keymap[77] = SDLK_NUMLOCK;
+ RO_keymap[78] = SDLK_PAGEDOWN;
+ RO_keymap[79] = SDLK_QUOTE;
+ RO_keymap[81] = SDLK_s;
+ RO_keymap[82] = SDLK_c;
+ RO_keymap[83] = SDLK_g;
+ RO_keymap[84] = SDLK_h;
+ RO_keymap[85] = SDLK_n;
+ RO_keymap[86] = SDLK_l;
+ RO_keymap[87] = SDLK_SEMICOLON;
+ RO_keymap[88] = SDLK_RIGHTBRACKET;
+ RO_keymap[89] = SDLK_DELETE;
+ RO_keymap[90] = SDLK_KP_MINUS;
+ RO_keymap[91] = SDLK_KP_MULTIPLY;
+ RO_keymap[93] = SDLK_EQUALS;
+ RO_keymap[94] = SDLK_BACKSLASH;
+ RO_keymap[96] = SDLK_TAB;
+ RO_keymap[97] = SDLK_z;
+ RO_keymap[98] = SDLK_SPACE;
+ RO_keymap[99] = SDLK_v;
+ RO_keymap[100] = SDLK_b;
+ RO_keymap[101] = SDLK_m;
+ RO_keymap[102] = SDLK_COMMA;
+ RO_keymap[103] = SDLK_PERIOD;
+ RO_keymap[104] = SDLK_SLASH;
+ RO_keymap[105] = SDLK_END;
+ RO_keymap[106] = SDLK_KP0;
+ RO_keymap[107] = SDLK_KP1;
+ RO_keymap[108] = SDLK_KP3;
+ RO_keymap[112] = SDLK_ESCAPE;
+ RO_keymap[113] = SDLK_F1;
+ RO_keymap[114] = SDLK_F2;
+ RO_keymap[115] = SDLK_F3;
+ RO_keymap[116] = SDLK_F5;
+ RO_keymap[117] = SDLK_F6;
+ RO_keymap[118] = SDLK_F8;
+ RO_keymap[119] = SDLK_F9;
+ RO_keymap[120] = SDLK_HASH;
+ RO_keymap[121] = SDLK_RIGHT;
+ RO_keymap[122] = SDLK_KP4;
+ RO_keymap[123] = SDLK_KP5;
+ RO_keymap[124] = SDLK_KP2;
+
+ SDL_memset(RO_pressed, 0, ROKEYBD_ARRAYSIZE);
+}
+
+
+/* Variable for mouse relative processing */
+int mouse_relative = 0;
+
+/* Check to see if we need to enter or leave mouse relative mode */
+
+void RISCOS_CheckMouseMode(_THIS)
+{
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
+ (this->input_grab != SDL_GRAB_OFF) ) {
+ mouse_relative = 1;
+ } else {
+ mouse_relative = 0;
+ }
+}
+
+
+void RISCOS_PollMouse(_THIS)
+{
+ RISCOS_PollMouseHelper(this, 1);
+}
+
+extern int mouseInWindow;
+
+void WIMP_PollMouse(_THIS)
+{
+ /* Only poll when mouse is over the window */
+ if (!mouseInWindow) return;
+
+ RISCOS_PollMouseHelper(this, 0);
+}
+
+/* Static variables so only changes are reported */
+static Sint16 last_x = -1, last_y = -1;
+static int last_buttons = 0;
+
+/* Share routine between WIMP and FULLSCREEN for polling mouse and
+ passing on events */
+void RISCOS_PollMouseHelper(_THIS, int fullscreen)
+{
+ _kernel_swi_regs regs;
+ static int starting = 1;
+
+ if (_kernel_swi(OS_Mouse, &regs, &regs) == NULL)
+ {
+ Sint16 new_x = regs.r[0]; /* Initialy get as OS units */
+ Sint16 new_y = regs.r[1];
+
+ /* Discard mouse events until they let go of the mouse after starting */
+ if (starting && regs.r[2] != 0)
+ return;
+ else
+ starting = 0;
+
+ if (new_x != last_x || new_y != last_y || last_buttons != regs.r[2])
+ {
+ /* Something changed so generate appropriate events */
+ int topLeftX, topLeftY; /* Top left OS units */
+ int x, y; /* Mouse position in SDL pixels */
+
+ if (fullscreen)
+ {
+ topLeftX = 0;
+ topLeftY = (this->hidden->height << this->hidden->yeig) - 1;
+ } else
+ {
+ int window_state[9];
+
+ /* Get current window state */
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ topLeftX = window_state[1];
+ topLeftY = window_state[4];
+ }
+
+ /* Convert co-ordinates to workspace */
+ x = new_x - topLeftX;
+ y = topLeftY - new_y; /* Y goes from top of window/screen */
+
+ /* Convert OS units to pixels */
+ x >>= this->hidden->xeig;
+ y >>= this->hidden->yeig;
+
+ if (last_x != new_x || last_y != new_y)
+ {
+ if (mouse_relative)
+ {
+ int centre_x = SDL_VideoSurface->w/2;
+ int centre_y = SDL_VideoSurface->h/2;
+
+ if (centre_x != x || centre_y != y)
+ {
+ if (SDL_VideoSurface) SDL_PrivateMouseMotion(0,1,x - centre_x, y - centre_y);
+ last_x = topLeftX + (centre_x << this->hidden->xeig);
+ last_y = topLeftY - (centre_y << this->hidden->yeig);
+
+ /* Re-centre the mouse pointer, so we still get relative
+ movement when the mouse is at the edge of the window
+ or screen.
+ */
+ {
+ unsigned char block[5];
+
+ block[0] = 3; /* OSWORD move pointer sub-reason code */
+ block[1] = last_x & 0xFF;
+ block[2] = (last_x >> 8) & 0xFF;
+ block[3] = last_y & 0xFF;
+ block[4] = (last_y >> 8) & 0xFF;
+
+ regs.r[0] = 21; /* OSWORD pointer stuff code */
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ }
+ }
+ } else
+ {
+ last_x = new_x;
+ last_y = new_y;
+ SDL_PrivateMouseMotion(0,0,x,y);
+ }
+ }
+
+ if (last_buttons != regs.r[2])
+ {
+ int changed = last_buttons ^ regs.r[2];
+ last_buttons = regs.r[2];
+ if (changed & 4) SDL_PrivateMouseButton((last_buttons & 4) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ if (changed & 2) SDL_PrivateMouseButton((last_buttons & 2) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
+ if (changed & 1) SDL_PrivateMouseButton((last_buttons & 1) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
+ }
+ }
+ }
+}
+
+void RISCOS_PollKeyboard()
+{
+ int which_key = ROKEY_LEFT_SHIFT;
+ int j;
+ int min_key, max_key;
+ SDL_keysym key;
+
+ /* Scan the keyboard to see what is pressed */
+ while (which_key <= ROKEY_LAST_KEY)
+ {
+ which_key = (_kernel_osbyte(121, which_key, 0) & 0xFF);
+ if (which_key != ROKEY_NONE)
+ {
+ switch(which_key)
+ {
+ /* Skip over mouse keys */
+ case ROKEY_LEFT_MOUSE:
+ case ROKEY_CENTRE_MOUSE:
+ case ROKEY_RIGHT_MOUSE:
+ which_key = ROKEY_RIGHT_MOUSE;
+ break;
+
+ /* Ignore keys that cause 2 internal number to be generated */
+ case 71: case 24: case 87: case 40:
+ break;
+
+ /* Ignore break as it can be latched on */
+ case 44:
+ break;
+
+ default:
+ RO_pressed[which_key] += 2;
+ break;
+ }
+ which_key++;
+ }
+ }
+
+ /* Generate key released messages */
+ min_key = ROKEY_LAST_KEY+1;
+ max_key = ROKEY_LEFT_SHIFT;
+
+ for (j = ROKEY_LEFT_SHIFT; j <= ROKEY_LAST_KEY; j++)
+ {
+ if (RO_pressed[j])
+ {
+ if (RO_pressed[j] == 1)
+ {
+ RO_pressed[j] = 0;
+ SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(j,&key,0));
+ } else
+ {
+ if (j < min_key) min_key = j;
+ if (j > max_key) max_key = j;
+ }
+ }
+ }
+
+ /* Generate key pressed messages */
+ for (j = min_key; j <= max_key; j++)
+ {
+ if (RO_pressed[j])
+ {
+ if (RO_pressed[j] == 2)
+ {
+ SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(j,&key,1));
+ }
+ RO_pressed[j] = 1;
+ }
+ }
+}
+
+static SDL_keysym *TranslateKey(int intkey, SDL_keysym *keysym, int pressed)
+{
+ /* Set the keysym information */
+ keysym->scancode = (unsigned char) intkey;
+ keysym->sym = RO_keymap[intkey];
+ keysym->mod = KMOD_NONE;
+ keysym->unicode = 0;
+ if ( pressed && SDL_TranslateUNICODE )
+ {
+ int state;
+ int ch;
+
+ state = (_kernel_osbyte(202, 0, 255) & 0xFF);
+
+ /*TODO: Take into account other keyboard layouts */
+
+ ch = keysym->sym; /* This should handle most unshifted keys */
+
+ if (intkey < 9 || ch == SDLK_UNKNOWN)
+ {
+ ch = 0;
+
+ } else if (state & 64) /* Control on */
+ {
+ ch = ch & 31;
+
+ } else
+ {
+ int topOfKey = 0;
+ if (state & 8) /* Shift on */
+ {
+ topOfKey = 1;
+ }
+
+ if ((state & 16) == 0) /* Caps lock is on */
+ {
+ if (ch >= SDLK_a && ch <= SDLK_z)
+ {
+ if ((state & 128) == 0) /* Shift Enable off */
+ {
+ /* All letter become upper case */
+ topOfKey = 1;
+ } else
+ {
+ /* Shift+Letters gives lower case */
+ topOfKey = 1 - topOfKey;
+ }
+ }
+ }
+
+ if (topOfKey)
+ {
+ /* Key produced with shift held down */
+
+ /* Letters just give upper case version */
+ if (ch >= SDLK_a && ch <= SDLK_z) ch = toupper(ch);
+ else
+ {
+ switch(ch)
+ {
+ case SDLK_HASH: ch = '~'; break;
+ case SDLK_QUOTE: ch = '@'; break;
+ case SDLK_COMMA: ch = '<'; break;
+ case SDLK_MINUS: ch = '_'; break;
+ case SDLK_PERIOD: ch = '>'; break;
+ case SDLK_SLASH: ch = '?'; break;
+
+ case SDLK_0: ch = ')'; break;
+ case SDLK_1: ch = '!'; break;
+ case SDLK_2: ch = '"'; break;
+ case SDLK_3: ch = '£'; break;
+ case SDLK_4: ch = '$'; break;
+ case SDLK_5: ch = '%'; break;
+ case SDLK_6: ch = '^'; break;
+ case SDLK_7: ch = '&'; break;
+ case SDLK_8: ch = '*'; break;
+ case SDLK_9: ch = '('; break;
+
+ case SDLK_SEMICOLON: ch = ':'; break;
+ case SDLK_EQUALS: ch = '+'; break;
+ case SDLK_LEFTBRACKET: ch = '{'; break;
+ case SDLK_BACKSLASH: ch = '|'; break;
+ case SDLK_RIGHTBRACKET: ch = '}'; break;
+ case SDLK_BACKQUOTE: ch = '¬'; break;
+
+ default:
+ ch = 0; /* Map to zero character if we don't understand it */
+ break;
+ }
+ }
+
+ } else if (ch > 126)
+ {
+ /* SDL key code < 126 map directly onto their Unicode equivalents */
+ /* Keypad 0 to 9 maps to numeric equivalent */
+ if (ch >= SDLK_KP0 && ch <= SDLK_KP9) ch = ch - SDLK_KP0 + '0';
+ else
+ {
+ /* Following switch maps other keys that produce an Ascii value */
+ switch(ch)
+ {
+ case SDLK_KP_PERIOD: ch = '.'; break;
+ case SDLK_KP_DIVIDE: ch = '/'; break;
+ case SDLK_KP_MULTIPLY: ch = '*'; break;
+ case SDLK_KP_MINUS: ch = '-'; break;
+ case SDLK_KP_PLUS: ch = '+'; break;
+ case SDLK_KP_EQUALS: ch = '='; break;
+
+ default:
+ /* If we don't know what it is set the Unicode to 0 */
+ ch = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ keysym->unicode = ch;
+ }
+ return(keysym);
+}
+
+/* end of SDL_riscosevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h
new file mode 100644
index 0000000..189b3c0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosevents_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_riscosvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void RISCOS_InitOSKeymap(_THIS);
+extern void FULLSCREEN_PumpEvents(_THIS);
+extern void WIMP_PumpEvents(_THIS);
+
+/* end of SDL_nullevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c
new file mode 100644
index 0000000..b4a0bff
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse.c
@@ -0,0 +1,371 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements mouse cursor shape definitions and positioning
+*/
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+static WMcursor *current_cursor = NULL;
+static WMcursor *defined_cursor = NULL;
+
+extern int mouseInWindow;
+
+/* Area to save cursor palette colours changed by SDL.
+ Actual values will be read before we change to the SDL cursor */
+static Uint8 wimp_cursor_palette[2][5] = {
+ {1, 25, 255, 255, 255},
+ {3, 25, 255, 255, 255}
+};
+
+static int cursor_palette_saved = 0;
+
+void WIMP_SaveCursorPalette();
+void WIMP_RestoreWimpCursor();
+void WIMP_SetSDLCursorPalette();
+
+
+void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ SDL_free(cursor->data);
+ SDL_free(cursor);
+}
+
+WMcursor *RISCOS_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ Uint8 *cursor_data;
+ Uint8 *ptr;
+ int i,j,k;
+ int data_byte, mask_byte;
+
+ /* Check to make sure the cursor size is okay */
+ if ( (w > 32) || (h > 32) ) {
+ SDL_SetError("Only with width and height <= 32 pixels are allowed");
+ return(NULL);
+ }
+
+ /* Allocate the cursor */
+ cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
+ if ( cursor == NULL ) {
+ SDL_SetError("Out of memory");
+ return(NULL);
+ }
+
+ /* Note: SDL says width must be a multiple of 8 */
+ cursor_data = SDL_malloc(w/4 * h);
+ if (cursor_data == NULL)
+ {
+ SDL_free(cursor);
+ SDL_SetError("Out of memory");
+ return(NULL);
+ }
+
+ cursor->w = w;
+ cursor->h = h;
+ cursor->hot_x = hot_x;
+ cursor->hot_y = hot_y;
+ cursor->data = cursor_data;
+
+
+/* Data / Mask Resulting pixel on screen
+ 0 / 1 White
+ 1 / 1 Black
+ 0 / 0 Transparent
+ 1 / 0 Inverted color if possible, black if not.
+*/
+ ptr = cursor_data;
+
+ for ( i=0; i<h; ++i )
+ {
+ for (j = 0; j < w/8; ++j)
+ {
+ data_byte = *data;
+ mask_byte = *mask;
+ *ptr++ = 0; /* Sets whole byte transparent */
+ *ptr = 0;
+ for (k = 0; k < 8; k++)
+ {
+ (*ptr) <<= 2;
+ if (data_byte & 1) *ptr |= 3; /* Black or inverted */
+ else if(mask_byte & 1) *ptr |= 1; /* White */
+ if ((k&3) == 3) ptr--;
+ data_byte >>= 1;
+ mask_byte >>= 1;
+ }
+
+ ptr+=3;
+ data++;
+ mask++;
+ }
+ }
+
+ return(cursor);
+}
+
+int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ current_cursor = cursor;
+
+ if (cursor == NULL)
+ {
+ _kernel_osbyte(106,0,0);
+ defined_cursor = NULL;
+ } else
+ {
+ WMcursor *old_cursor = defined_cursor;
+
+ if (cursor != defined_cursor)
+ {
+ Uint8 cursor_def[10];
+
+ cursor_def[0] = 0;
+ cursor_def[1] = 2; /* Use shape number 2 */
+ cursor_def[2] = cursor->w/4; /* Width in bytes */
+ cursor_def[3] = cursor->h; /* Height (h) in pixels */
+ cursor_def[4] = cursor->hot_x; /* ActiveX in pixels from left */
+ cursor_def[5] = cursor->hot_y; /* ActiveY in pixels from top */
+ cursor_def[6] = ((int)(cursor->data) & 0xFF); /* Least significant byte of pointer to data */
+ cursor_def[7] = ((int)(cursor->data) >> 8) & 0xFF; /* ... */
+ cursor_def[8] = ((int)(cursor->data) >> 16) & 0xFF; /* ... */
+ cursor_def[9] = ((int)(cursor->data) >> 24) & 0xFF; /* Most significant byte of pointer to data */
+
+ if (_kernel_osword(21, (int *)cursor_def) != 0)
+ {
+ SDL_SetError("RISCOS couldn't create the cursor to show");
+ return(0);
+ }
+ defined_cursor = cursor;
+ }
+
+ if (old_cursor == NULL)
+ {
+ /* First time or reshow in window, so save/setup palette */
+ if (!cursor_palette_saved)
+ {
+ WIMP_SaveCursorPalette();
+ }
+ WIMP_SetSDLCursorPalette();
+ }
+
+ _kernel_osbyte(106, 2, 0);
+ }
+
+ return(1);
+}
+
+void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ Uint8 move_block[5];
+ int eig_block[3];
+ _kernel_swi_regs regs;
+ int os_x, os_y;
+
+ eig_block[0] = 4; /* X eig factor */
+ eig_block[1] = 5; /* Y eig factor */
+ eig_block[2] = -1; /* End of list of variables to request */
+
+ regs.r[0] = (int)eig_block;
+ regs.r[1] = (int)eig_block;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+
+ os_x = x << eig_block[0];
+ os_y = y << eig_block[1];
+
+ move_block[0] = 3; /* Move cursor */
+ move_block[1] = os_x & 0xFF;
+ move_block[2] = (os_x >> 8) & 0xFF;
+ move_block[3] = os_y & 0xFF;
+ move_block[4] = (os_y >> 8) & 0xFF;
+
+ _kernel_osword(21, (int *)move_block);
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
+
+/* Reshow cursor when mouse re-enters the window */
+void WIMP_ReshowCursor(_THIS)
+{
+ defined_cursor = NULL;
+ cursor_palette_saved = 0;
+ RISCOS_ShowWMCursor(this, current_cursor);
+}
+
+void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ _kernel_swi_regs regs;
+ int window_state[9];
+ char block[5];
+ int osX, osY;
+
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ osX = (x << this->hidden->xeig) + window_state[1];
+ osY = window_state[4] - (y << this->hidden->yeig);
+
+ block[0] = 3;
+ block[1] = osX & 0xFF;
+ block[2] = (osX >> 8) & 0xFF;
+ block[3] = osY & 0xFF;
+ block[4] = (osY >> 8) & 0xFF;
+
+ regs.r[0] = 21;
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
+int WIMP_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ if (mouseInWindow) return RISCOS_ShowWMCursor(this, cursor);
+ else current_cursor = cursor;
+
+ return 1;
+}
+
+SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ /* In fullscreen mode we don't need to do anything */
+ if (mode < SDL_GRAB_FULLSCREEN)
+ {
+ _kernel_swi_regs regs;
+ unsigned char block[9];
+ block[0] = 1; /* Define mouse cursor bounding block */
+
+ if ( mode == SDL_GRAB_OFF )
+ {
+ /* Clip to whole screen */
+
+ int r = (this->hidden->screen_width << this->hidden->xeig) - 1;
+ int t = (this->hidden->screen_height << this->hidden->yeig) - 1;
+
+ block[1] = 0; block[2] = 0; /* Left*/
+ block[3] = 0; block[4] = 0; /* Bottom */
+ block[5] = r & 0xFF; block[6] = (r >> 8) & 0xFF; /* Right */
+ block[7] = t & 0xFF; block[8] = (t >> 8) & 0xFF; /* Top */
+ } else
+ {
+ /* Clip to window */
+ unsigned char window_state[36];
+
+ *((int *)window_state) = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ block[1] = window_state[4];
+ block[2] = window_state[5];
+ block[3] = window_state[8];
+ block[4] = window_state[9];
+ block[5] = window_state[12];
+ block[6] = window_state[13];
+ block[7] = window_state[16];
+ block[8] = window_state[17];
+
+ }
+
+ regs.r[0] = 21; /* OS word code */
+ regs.r[1] = (int)block;
+ _kernel_swi(OS_Word, &regs, &regs);
+ }
+
+ return mode;
+}
+
+/* Save mouse cursor palette to be restore when we are no longer
+ defining a cursor */
+
+void WIMP_SaveCursorPalette()
+{
+ _kernel_swi_regs regs;
+ int colour;
+
+ for (colour = 0; colour < 2; colour++)
+ {
+ regs.r[0] = (int)wimp_cursor_palette[colour][0];
+ regs.r[1] = 25;
+ /* Read settings with OS_ReadPalette */
+ if (_kernel_swi(0x2f, &regs, &regs) == NULL)
+ {
+ wimp_cursor_palette[colour][2] = (unsigned char)((regs.r[2] >> 8) & 0xFF);
+ wimp_cursor_palette[colour][3] = (unsigned char)((regs.r[2] >> 16) & 0xFF);
+ wimp_cursor_palette[colour][4] = (unsigned char)((regs.r[2] >> 24) & 0xFF);
+ }
+ }
+
+ cursor_palette_saved = 1;
+}
+
+/* Restore the WIMP's cursor when we leave the SDL window */
+void WIMP_RestoreWimpCursor()
+{
+ int colour;
+
+ /* Reset to pointer shape 1 */
+ _kernel_osbyte(106, 1, 0);
+
+ /* Reset pointer colours */
+ if (cursor_palette_saved)
+ {
+ for (colour = 0; colour < 2; colour++)
+ {
+ _kernel_osword(12, (int *)wimp_cursor_palette[colour]);
+ }
+ }
+ cursor_palette_saved = 0;
+}
+
+/* Set palette used for SDL mouse cursors */
+void WIMP_SetSDLCursorPalette()
+{
+ /* First time set up the mouse colours */
+ Uint8 block[5];
+
+ /* Set up colour 1 as white */
+ block[0] = 1; /* Colour to change 1 - 3 */
+ block[1] = 25; /* Set pointer colour */
+ block[2] = 255; /* red component*/
+ block[3] = 255; /* green component */
+ block[4] = 255; /* blue component*/
+ _kernel_osword(12, (int *)block);
+
+ /* Set colour 3 to back */
+ block[0] = 3; /* Colour to change 1 - 3 */
+ block[1] = 25; /* Set pointer colour*/
+ block[2] = 0; /* red component*/
+ block[3] = 0; /* green component */
+ block[4] = 0; /* blue component*/
+ _kernel_osword(12, (int *)block);
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h
new file mode 100644
index 0000000..9019cb4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosmouse_c.h
@@ -0,0 +1,44 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_riscosvideo.h"
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int w;
+ int h;
+ int hot_x;
+ int hot_y;
+ Uint8 *data;
+};
+
+/* Functions to be exported */
+void RISCOS_FreeWMCursor(_THIS, WMcursor *cursor);
+WMcursor *RISCOS_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+
+int RISCOS_ShowWMCursor(_THIS, WMcursor *cursor);
+void FULLSCREEN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
+int WIMP_ShowWMCursor(_THIS, WMcursor *cursor);
+void WIMP_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c
new file mode 100644
index 0000000..70b2f91
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscossprite.c
@@ -0,0 +1,265 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements Sprite plotting code for wimp display.window
+*/
+
+#include "kernel.h"
+#include "swis.h"
+
+#include "SDL_stdinc.h"
+#include "SDL_riscosvideo.h"
+
+extern void WIMP_ReadModeInfo(_THIS);
+
+void WIMP_PaletteChanged(_THIS);
+
+
+/* Create sprite buffer for screen */
+
+unsigned char *WIMP_CreateBuffer(int width, int height, int bpp)
+{
+ int size;
+ char sprite_name[12] = "display";
+ unsigned char *buffer;
+ _kernel_swi_regs regs;
+ int bytesPerPixel;
+ int bytesPerRow;
+ int offsetToSpriteData = 60;
+
+ switch(bpp)
+ {
+ case 32: bytesPerPixel = 4; break;
+ case 16: bytesPerPixel = 2; break;
+ case 8:
+ bytesPerPixel = 1;
+ offsetToSpriteData += 2048; /* Add in size of palette */
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ bytesPerRow = bytesPerPixel * width;
+
+ if ((bytesPerRow & 3) != 0)
+ {
+ bytesPerRow += 4 - (bytesPerRow & 3);
+ }
+ size = bytesPerRow * height;
+
+ buffer = SDL_malloc( (size_t) size + offsetToSpriteData );
+ if (!buffer) return NULL;
+
+ /* Initialise a sprite area */
+
+ *(unsigned int *)buffer = size + offsetToSpriteData;
+ *(unsigned int *)(buffer + 8) = 16;
+
+ regs.r[0] = 256+9;
+ regs.r[1] = (unsigned int)buffer;
+ _kernel_swi(OS_SpriteOp, &regs, &regs);
+
+ regs.r[0] = 256+15;
+ regs.r[1] = (unsigned int)buffer;
+ regs.r[2] = (unsigned int)&sprite_name;
+ regs.r[3] = 0; /* Palette flag: 0 = no palette */
+ regs.r[4] = width;
+ regs.r[5] = height;
+ if (bpp == 8)
+ {
+ /* Use old style mode number */
+ regs.r[6] = 28; /* 8bpp 90x90dpi */
+ } else
+ {
+ regs.r[6] = (((bpp == 16) ? 5 : 6) << 27) /* Type 6 = 32bpp sprite, 5 = 16bpp sprite */
+ | (90 << 14) /* Vertical dpi */
+ | (90 << 1) /* Horizontal dpi */
+ | 1; /* Marker to distinguish between mode selectors and sprite modes */
+ }
+ if (_kernel_swi(OS_SpriteOp, &regs, &regs) == NULL)
+ {
+ if (bpp == 8)
+ {
+ /* Modify sprite to take into account 256 colour palette */
+ int *sprite = (int *)(buffer + 16);
+ /* Adjust sprite offsets */
+ sprite[0] += 2048;
+ sprite[8] += 2048;
+ sprite[9] += 2048;
+ /* Adjust sprite area next free pointer */
+ (*(int *)(buffer+12)) += 2048;
+
+ /* Don't need to set up palette as SDL sets up the default
+ 256 colour palette */
+/* {
+ int *pal = sprite + 11;
+ unsigned int j;
+ unsigned int entry;
+ for (j = 0; j < 255; j++)
+ {
+ entry = (j << 24) | (j << 16) | (j << 8);
+ *pal++ = entry;
+ *pal++ = entry;
+ }
+ }
+*/
+ }
+ } else
+ {
+ SDL_free(buffer);
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+/* Setup translation buffers for the sprite plotting */
+
+void WIMP_SetupPlotInfo(_THIS)
+{
+ _kernel_swi_regs regs;
+ int *sprite = ((int *)this->hidden->bank[1])+4;
+
+ regs.r[0] = (unsigned int)this->hidden->bank[1];
+ regs.r[1] = (unsigned int)sprite;
+ regs.r[2] = -1; /* Current mode */
+ regs.r[3] = -1; /* Current palette */
+ regs.r[4] = 0; /* Get size of buffer */
+ regs.r[5] = 1|2|16; /* R1 - pointer to sprite and can use full palette words */
+ regs.r[6] = 0;
+ regs.r[7] = 0;
+
+ if (this->hidden->pixtrans) SDL_free(this->hidden->pixtrans);
+ this->hidden->pixtrans = 0;
+
+ /* Get the size required for the buffer */
+ _kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
+ if (regs.r[4])
+ {
+ this->hidden->pixtrans = SDL_malloc(regs.r[4]);
+
+ regs.r[4] = (unsigned int)this->hidden->pixtrans;
+ /* Actually read the buffer */
+ _kernel_swi(ColourTrans_GenerateTable, &regs, &regs);
+ }
+}
+
+/* Plot the sprite in the given context */
+void WIMP_PlotSprite(_THIS, int x, int y)
+{
+ _kernel_swi_regs regs;
+ _kernel_oserror *err;
+
+ regs.r[0] = 52 + 512;
+ regs.r[1] = (unsigned int)this->hidden->bank[1];
+ regs.r[2] = (unsigned int)this->hidden->bank[1]+16;
+ regs.r[3] = x;
+ regs.r[4] = y;
+ regs.r[5] = 0|32; /* Overwrite screen and pixtrans contains wide colour entries */
+ regs.r[6] = 0; /* No scale factors i.e. 1:1 */
+ regs.r[7] = (int)this->hidden->pixtrans;
+
+ if ((err = _kernel_swi(OS_SpriteOp, &regs, &regs)) != 0)
+ {
+ int *p = (int *)this->hidden->pixtrans;
+ printf("OS_SpriteOp failed \n%s\n",err->errmess);
+ printf("pixtrans %d\n", (int)this->hidden->pixtrans);
+ printf("%x %x %x\n", p[0], p[1], p[2]);
+ }
+}
+
+
+/* Wimp mode has changes so update colour mapping and pixel sizes
+ of windows and the sprites they plot */
+
+void WIMP_ModeChanged(_THIS)
+{
+ int oldXeig = this->hidden->xeig;
+ int oldYeig = this->hidden->yeig;
+
+ WIMP_ReadModeInfo(this);
+
+ if (oldXeig == this->hidden->xeig && oldYeig == this->hidden->yeig)
+ {
+ /* Only need to update the palette */
+ WIMP_PaletteChanged(this);
+ } else
+ {
+ _kernel_swi_regs regs;
+ int window_state[9];
+ int extent[4];
+ int currWidth, currHeight;
+ int newWidth, newHeight;
+
+ /* Need to resize windows and update the palette */
+ WIMP_SetupPlotInfo(this);
+
+
+ window_state[0] = this->hidden->window_handle;
+ regs.r[1] = (unsigned int)window_state;
+ _kernel_swi(Wimp_GetWindowState, &regs, &regs);
+
+ currWidth = window_state[3] - window_state[1];
+ currHeight = window_state[4] - window_state[2];
+
+ newWidth = (currWidth >> oldXeig) << this->hidden->xeig;
+ newHeight = (currHeight >> oldYeig) << this->hidden->yeig;
+ /* Need to avoid extent getting too small for visible part
+ of window */
+ extent[0] = 0;
+ if (currHeight <= newHeight)
+ {
+ extent[1] = -newHeight;
+ } else
+ {
+ extent[1] = -currHeight;
+ }
+ if (currWidth <= newWidth)
+ {
+ extent[2] = newWidth;
+ } else
+ {
+ extent[2] = currWidth;
+ }
+ extent[3] = 0;
+
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = (int)extent;
+ _kernel_swi(Wimp_SetExtent, &regs, &regs);
+
+ /*TODO: May need to set flag to resize window on next open */
+ }
+}
+
+/* Palette has changed so update palettes used for windows sprites */
+
+void WIMP_PaletteChanged(_THIS)
+{
+ WIMP_SetupPlotInfo(this);
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c
new file mode 100644
index 0000000..67dc3e2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.c
@@ -0,0 +1,350 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS
+ 26 March 2003
+
+ File includes routines for:
+ Setting up as a WIMP Task
+ Reading information about the current desktop
+ Storing information before a switch to full screen
+ Restoring desktop after switching to full screen
+*/
+
+#include "kernel.h"
+#include "swis.h"
+
+#include "SDL_stdinc.h"
+#include "SDL_riscostask.h"
+
+#if !SDL_THREADS_DISABLED
+#include <pthread.h>
+pthread_t main_thread;
+#endif
+
+/* RISC OS variables */
+
+static int task_handle = 0;
+static int wimp_version = 0;
+
+/* RISC OS variables to help compatability with certain programs */
+int riscos_backbuffer = 0; /* Create a back buffer in system memory for full screen mode */
+int riscos_closeaction = 1; /* Close icon action */
+
+static int stored_mode = -1; /* -1 when in desktop, mode number or pointer when full screen */
+
+extern int mouseInWindow; /* Mouse is in WIMP window */
+
+/* Local function */
+
+static int RISCOS_GetTaskName(char *task_name, size_t maxlen);
+
+/* Uncomment next line to copy mode changes/restores to stderr */
+/* #define DUMP_MODE */
+#ifdef DUMP_MODE
+#include "stdio.h"
+static void dump_mode()
+{
+ fprintf(stderr, "mode %d\n", stored_mode);
+ if (stored_mode < -1 || stored_mode >= 256)
+ {
+ int blockSize = 0;
+ int *storeBlock = (int *)stored_mode;
+
+ while(blockSize < 5 || storeBlock[blockSize] != -1)
+ {
+ fprintf(stderr, " %d\n", storeBlock[blockSize++]);
+ }
+ }
+}
+#endif
+
+/******************************************************************
+
+ Initialise as RISC OS Wimp task
+
+*******************************************************************/
+
+int RISCOS_InitTask()
+{
+ char task_name[32];
+ _kernel_swi_regs regs;
+ int messages[4];
+
+ if (RISCOS_GetTaskName(task_name, SDL_arraysize(task_name)) == 0) return 0;
+
+ messages[0] = 9; /* Palette changed */
+ messages[1] = 0x400c1; /* Mode changed */
+ messages[2] = 8; /* Pre quit */
+ messages[2] = 0;
+
+ regs.r[0] = (unsigned int)360; /* Minimum version 3.6 */
+ regs.r[1] = (unsigned int)0x4b534154;
+ regs.r[2] = (unsigned int)task_name;
+ regs.r[3] = (unsigned int)messages;
+
+ if (_kernel_swi(Wimp_Initialise, &regs, &regs) == 0)
+ {
+ wimp_version = regs.r[0];
+ task_handle = regs.r[1];
+ return 1;
+ }
+
+#if !SDL_THREADS_DISABLED
+ main_thread = pthread_self();
+#endif
+
+ return 0;
+}
+
+/*********************************************************************
+
+ Close down application on exit.
+
+**********************************************************************/
+
+void RISCOS_ExitTask()
+{
+ _kernel_swi_regs regs;
+
+ if (stored_mode == -1)
+ {
+ /* Ensure cursor is put back to standard pointer shape if
+ we have been running in a window */
+ _kernel_osbyte(106,1,0);
+ }
+
+ /* Ensure we end up back in the wimp */
+ RISCOS_RestoreWimpMode();
+
+ /* Neatly exit the task */
+ regs.r[0] = task_handle;
+ regs.r[1] = (unsigned int)0x4b534154;
+ _kernel_swi(Wimp_CloseDown, &regs, &regs);
+ task_handle = 0;
+}
+
+/**************************************************************************
+
+ Get the name of the task for the desktop.
+
+ Param: task_name - name of task 32 characters.
+
+ Returns: 1 is successful, otherwise 0
+
+ Notes: Works by getting using OS_GetEnv to get the command line
+ used to run the program and then parsing a name from it
+ as follows.
+
+ 1. Use name after final period if not !RunImage
+ 2. If name is !RunImage then process item before the period
+ in front of !RunImage.
+ 3. If directory name use that
+ 4. if in form <XXX$Dir> use the XXX.
+
+ Finally once this value has been retrieved use it unless
+ there is a variable set up in the form SDL$<name>$TaskName
+ in which case the value of this variable will be used.
+
+ Now also gets other RISC OS configuration varibles
+ SDL$<name>$BackBuffer - set to 1 to use a system memory backbuffer in fullscreen mode
+ so updates wait until a call to SDL_UpdateRects. (default 0)
+ This is required for programmes where they have assumed this is
+ always the case which is contrary to the documentation.
+ SDL$<name>$CloseAction
+ 0 Don't show close icon
+ 1 Show close icon
+
+***************************************************************************/
+
+int RISCOS_GetTaskName(char *task_name, size_t maxlen)
+{
+ _kernel_swi_regs regs;
+
+ task_name[0] = 0;
+
+ /* Figure out a sensible task name */
+ if (_kernel_swi(OS_GetEnv, &regs, &regs) == 0)
+ {
+ char *command_line = (char *)regs.r[0];
+ size_t len = SDL_strlen(command_line)+1;
+ char *buffer = SDL_stack_alloc(char, len);
+ char *env_var;
+ char *p;
+
+ SDL_strlcpy(buffer, command_line, len);
+ p = SDL_strchr(buffer, ' ');
+ if (p) *p = 0;
+ p = SDL_strrchr(buffer, '.');
+ if (p == 0) p = buffer;
+ if (stricmp(p+1,"!RunImage") == 0)
+ {
+ *p = 0;
+ p = SDL_strrchr(buffer, '.');
+ if (p == 0) p = buffer;
+ }
+ if (*p == '.') p++;
+ if (*p == '!') p++; /* Skip "!" at beginning of application directories */
+
+ if (*p == '<')
+ {
+ // Probably in the form <appname$Dir>
+ char *q = SDL_strchr(p, '$');
+ if (q == 0) q = SDL_strchr(p,'>'); /* Use variable name if not */
+ if (q) *q = 0;
+ p++; /* Move over the < */
+ }
+
+ if (*p)
+ {
+ /* Read variables that effect the RISC OS SDL engine for this task */
+ len = SDL_strlen(p) + 18; /* 18 is larger than the biggest variable name */
+ env_var = SDL_stack_alloc(char, len);
+ if (env_var)
+ {
+ char *env_val;
+
+ /* See if a variable of form SDL$<dirname>$TaskName exists */
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$TaskName", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val) SDL_strlcpy(task_name, env_val, maxlen);
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$BackBuffer", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val) riscos_backbuffer = atoi(env_val);
+
+ SDL_strlcpy(env_var, "SDL$", len);
+ SDL_strlcat(env_var, p, len);
+ SDL_strlcat(env_var, "$CloseAction", len);
+
+ env_val = SDL_getenv(env_var);
+ if (env_val && SDL_strcmp(env_val,"0") == 0) riscos_closeaction = 0;
+
+ SDL_stack_free(env_var);
+ }
+
+ if (!*task_name) SDL_strlcpy(task_name, p, maxlen);
+ }
+
+ SDL_stack_free(buffer);
+ }
+
+ if (task_name[0] == 0) SDL_strlcpy(task_name, "SDL Task", maxlen);
+
+ return 1;
+}
+
+/*****************************************************************
+
+ Store the current desktop screen mode if we are in the desktop.
+
+******************************************************************/
+
+void RISCOS_StoreWimpMode()
+{
+ _kernel_swi_regs regs;
+
+ /* Don't store if in full screen mode */
+ if (stored_mode != -1) return;
+
+ regs.r[0] = 1;
+ _kernel_swi(OS_ScreenMode, &regs, &regs);
+ if (regs.r[1] >= 0 && regs.r[1] < 256) stored_mode = regs.r[1];
+ else
+ {
+ int blockSize = 0;
+ int *retBlock = (int *)regs.r[1];
+ int *storeBlock;
+ int j;
+
+ while(blockSize < 5 || retBlock[blockSize] != -1) blockSize++;
+ blockSize++;
+ storeBlock = (int *)SDL_malloc(blockSize * sizeof(int));
+ retBlock = (int *)regs.r[1];
+ for ( j = 0; j < blockSize; j++)
+ storeBlock[j] = retBlock[j];
+
+ stored_mode = (int)storeBlock;
+ }
+#if DUMP_MODE
+ fprintf(stderr, "Stored "); dump_mode();
+#endif
+}
+
+/*****************************************************************
+
+ Restore desktop screen mode if we are in full screen mode.
+
+*****************************************************************/
+
+void RISCOS_RestoreWimpMode()
+{
+ _kernel_swi_regs regs;
+
+ /* Only need to restore if we are in full screen mode */
+ if (stored_mode == -1) return;
+
+#if DUMP_MODE
+ fprintf(stderr, "Restored"); dump_mode();
+#endif
+
+ regs.r[0] = stored_mode;
+ _kernel_swi(Wimp_SetMode, &regs, &regs);
+ if (stored_mode < 0 || stored_mode > 256)
+ {
+ SDL_free((int *)stored_mode);
+ }
+ stored_mode = -1;
+
+ /* Flush keyboard buffer to dump the keystrokes we've already polled */
+ regs.r[0] = 21;
+ regs.r[1] = 0; /* Keyboard buffer number */
+ _kernel_swi(OS_Byte, &regs, &regs);
+
+ mouseInWindow = 0;
+
+}
+
+/*********************************************************************
+
+ Get version of Wimp running when task was initialised.
+
+*********************************************************************/
+
+int RISCOS_GetWimpVersion()
+{
+ return wimp_version;
+}
+
+int RISCOS_GetTaskHandle()
+{
+ return task_handle;
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h
new file mode 100644
index 0000000..5744afa
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscostask.h
@@ -0,0 +1,39 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ This file added by Alan Buckley (alan_baa@hotmail.com) to support RISC OS
+ 26 March 2003
+*/
+
+/* Task initialisation/Clean up */
+
+extern int RISCOS_InitTask();
+extern void RISCOS_ExitTask();
+extern int RISCOS_GetWimpVersion();
+extern int RISCOS_GetTaskHandle();
+
+
+/* Wimp mode saveing/restoring */
+extern void RISCOS_StoreWimpMode();
+extern void RISCOS_RestoreWimpMode();
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c
new file mode 100644
index 0000000..bae5e37
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.c
@@ -0,0 +1,316 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 23 March 2003
+
+ Implements RISC OS display device management.
+ Routines for full screen and wimp modes are split
+ into other source files.
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+#define RISCOSVID_DRIVER_NAME "riscos"
+
+/* Initialization/Query functions */
+static int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static void RISCOS_VideoQuit(_THIS);
+
+static SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+
+int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info);
+
+int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
+/* Mouse checking */
+void RISCOS_CheckMouseMode(_THIS);
+extern SDL_GrabMode RISCOS_GrabInput(_THIS, SDL_GrabMode mode);
+
+/* Fullscreen mode functions */
+extern SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+extern void FULLSCREEN_BuildModeList(_THIS);
+extern void FULLSCREEN_SetDeviceMode(_THIS);
+extern int FULLSCREEN_ToggleFromWimp(_THIS);
+
+/* Wimp mode functions */
+extern SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+extern void WIMP_DeleteWindow(_THIS);
+extern int WIMP_ToggleFromFullScreen(_THIS);
+
+/* Hardware surface functions - common to WIMP and FULLSCREEN */
+static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface);
+static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* RISC OS driver bootstrap functions */
+
+static int RISCOS_Available(void)
+{
+ return(1);
+}
+
+static void RISCOS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *RISCOS_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = RISCOS_VideoInit;
+ device->VideoQuit = RISCOS_VideoQuit;
+
+ device->ListModes = RISCOS_ListModes;
+ device->SetVideoMode = RISCOS_SetVideoMode;
+ device->CreateYUVOverlay = NULL;
+ device->AllocHWSurface = RISCOS_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = RISCOS_LockHWSurface;
+ device->UnlockHWSurface = RISCOS_UnlockHWSurface;
+ device->FreeHWSurface = RISCOS_FreeHWSurface;
+
+ device->FreeWMCursor = RISCOS_FreeWMCursor;
+ device->CreateWMCursor = RISCOS_CreateWMCursor;
+ device->CheckMouseMode = RISCOS_CheckMouseMode;
+ device->GrabInput = RISCOS_GrabInput;
+
+ device->InitOSKeymap = RISCOS_InitOSKeymap;
+
+ device->GetWMInfo = RISCOS_GetWmInfo;
+
+ device->free = RISCOS_DeleteDevice;
+
+/* Can't get Toggle screen to work if program starts up in Full screen mode so
+ disable it here and re-enable it when a wimp screen is chosen */
+ device->ToggleFullScreen = NULL; /*RISCOS_ToggleFullScreen;*/
+
+ /* Set other entries for fullscreen mode */
+ FULLSCREEN_SetDeviceMode(device);
+
+ /* Mouse pointer needs to use the WIMP ShowCursor version so
+ that it doesn't modify the pointer until the SDL Window is
+ entered or the application goes full screen */
+ device->ShowWMCursor = WIMP_ShowWMCursor;
+
+ return device;
+}
+
+VideoBootStrap RISCOS_bootstrap = {
+ RISCOSVID_DRIVER_NAME, "RISC OS video driver",
+ RISCOS_Available, RISCOS_CreateDevice
+};
+
+
+int RISCOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ _kernel_swi_regs regs;
+ int vars[4], vals[3];
+
+ if (RISCOS_InitTask() == 0)
+ {
+ SDL_SetError("Unable to start task");
+ return 0;
+ }
+
+ vars[0] = 9; /* Log base 2 bpp */
+ vars[1] = 11; /* XWndLimit - num x pixels -1 */
+ vars[2] = 12; /* YWndLimit - num y pixels -1 */
+ vars[3] = -1; /* Terminate list */
+ regs.r[0] = (int)vars;
+ regs.r[1] = (int)vals;
+
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+ vformat->BitsPerPixel = (1 << vals[0]);
+
+ /* Determine the current screen size */
+ this->info.current_w = vals[1] + 1;
+ this->info.current_h = vals[2] + 1;
+
+ /* Minimum bpp for SDL is 8 */
+ if (vformat->BitsPerPixel < 8) vformat->BitsPerPixel = 8;
+
+
+ switch (vformat->BitsPerPixel)
+ {
+ case 15:
+ case 16:
+ vformat->Bmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Rmask = 0x0000001f;
+ vformat->BitsPerPixel = 16; /* SDL wants actual number of bits used */
+ vformat->BytesPerPixel = 2;
+ break;
+
+ case 24:
+ case 32:
+ vformat->Bmask = 0x00ff0000;
+ vformat->Gmask = 0x0000ff00;
+ vformat->Rmask = 0x000000ff;
+ vformat->BytesPerPixel = 4;
+ break;
+
+ default:
+ vformat->Bmask = 0;
+ vformat->Gmask = 0;
+ vformat->Rmask = 0;
+ vformat->BytesPerPixel = 1;
+ break;
+ }
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ /* We're done! */
+ return(0);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void RISCOS_VideoQuit(_THIS)
+{
+ RISCOS_ExitTask();
+
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ this->hidden->alloc_bank = 0;
+}
+
+
+SDL_Rect **RISCOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ {
+ /* Build mode list when first required. */
+ if (SDL_nummodes[0] == 0) FULLSCREEN_BuildModeList(this);
+
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+ } else
+ return (SDL_Rect **)-1;
+}
+
+
+/* Set up video mode */
+SDL_Surface *RISCOS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if (flags & SDL_FULLSCREEN)
+ {
+ RISCOS_StoreWimpMode();
+ /* Dump wimp window on switch to full screen */
+ if (this->hidden->window_handle) WIMP_DeleteWindow(this);
+
+ return FULLSCREEN_SetVideoMode(this, current, width, height, bpp, flags);
+ } else
+ {
+ RISCOS_RestoreWimpMode();
+ return WIMP_SetVideoMode(this, current, width, height, bpp, flags);
+ }
+}
+
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int RISCOS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void RISCOS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int RISCOS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void RISCOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+
+int RISCOS_GetWmInfo(_THIS, SDL_SysWMinfo *info)
+{
+ SDL_VERSION(&(info->version));
+ info->wimpVersion = RISCOS_GetWimpVersion();
+ info->taskHandle = RISCOS_GetTaskHandle();
+ info->window = this->hidden->window_handle;
+
+ return 1;
+}
+/* Toggle full screen mode.
+ Returns 1 if successful otherwise 0
+*/
+
+int RISCOS_ToggleFullScreen(_THIS, int fullscreen)
+{
+ if (fullscreen)
+ {
+ return FULLSCREEN_ToggleFromWimp(this);
+ } else
+ {
+ return WIMP_ToggleFromFullScreen(this);
+ }
+
+ return 0;
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h
new file mode 100644
index 0000000..7c717ad
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_riscosvideo.h
@@ -0,0 +1,62 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_riscosvideo_h
+#define _SDL_riscosvideo_h
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+
+/* Private display data */
+
+struct SDL_PrivateVideoData {
+ unsigned char *bank[2];
+ int current_bank;
+ unsigned char *alloc_bank;
+ int height;
+ int xeig;
+ int yeig;
+ int screen_bpp;
+ int screen_width;
+ int screen_height;
+ char *pixtrans;
+
+ /* Wimp variables */
+ unsigned int window_handle;
+ char title[256];
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+};
+
+/* Old variable names */
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+
+#endif /* _SDL_risosvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c
new file mode 100644
index 0000000..4999664
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimppoll.c
@@ -0,0 +1,330 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements Pumping of events and WIMP polling
+*/
+
+#include "SDL.h"
+#include "SDL_syswm.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+#include "../../timer/SDL_timer_c.h"
+
+#include "memory.h"
+#include "stdlib.h"
+#include "ctype.h"
+
+#include "kernel.h"
+#include "swis.h"
+#include "unixlib/os.h"
+
+#if !SDL_THREADS_DISABLED
+#include <pthread.h>
+#endif
+
+/* Local functions */
+void WIMP_Poll(_THIS, int waitTime);
+void WIMP_SetFocus(int win);
+
+/* SDL_riscossprite functions */
+void WIMP_PlotSprite(_THIS, int x, int y);
+void WIMP_ModeChanged(_THIS);
+void WIMP_PaletteChanged(_THIS);
+
+
+extern void WIMP_PollMouse(_THIS);
+extern void RISCOS_PollKeyboard();
+
+#if SDL_THREADS_DISABLED
+/* Timer running function */
+extern void RISCOS_CheckTimer();
+#else
+extern int riscos_using_threads;
+#endif
+
+/* Mouse cursor handling */
+extern void WIMP_ReshowCursor(_THIS);
+extern void WIMP_RestoreWimpCursor();
+
+int hasFocus = 0;
+int mouseInWindow = 0;
+
+/* Flag to ensure window is correct size after a mode change */
+static int resizeOnOpen = 0;
+
+void WIMP_PumpEvents(_THIS)
+{
+ WIMP_Poll(this, 0);
+ if (hasFocus) RISCOS_PollKeyboard();
+ if (mouseInWindow) WIMP_PollMouse(this);
+#if SDL_THREADS_DISABLED
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
+
+
+void WIMP_Poll(_THIS, int waitTime)
+{
+ _kernel_swi_regs regs;
+ int message[64];
+ unsigned int code;
+ int pollMask = 0;
+ int doPoll = 1;
+ int sysEvent;
+ int sdlWindow = this->hidden->window_handle;
+
+ if (this->PumpEvents != WIMP_PumpEvents) return;
+
+ if (waitTime > 0)
+ {
+ _kernel_swi(OS_ReadMonotonicTime, &regs, &regs);
+ waitTime += regs.r[0];
+ }
+
+ while (doPoll)
+ {
+#if !SDL_THREADS_DISABLED
+ /* Stop thread callbacks while program is paged out */
+ if (riscos_using_threads) __pthread_stop_ticker();
+#endif
+
+ if (waitTime <= 0)
+ {
+ regs.r[0] = pollMask; /* Poll Mask */
+ /* For no wait time mask out null event so we wait until something happens */
+ if (waitTime < 0) regs.r[0] |= 1;
+ regs.r[1] = (int)message;
+ _kernel_swi(Wimp_Poll, &regs, &regs);
+ } else
+ {
+ regs.r[0] = pollMask;
+ regs.r[1] = (int)message;
+ regs.r[2] = waitTime;
+ _kernel_swi(Wimp_PollIdle, &regs, &regs);
+ }
+
+ /* Flag to specify if we post a SDL_SysWMEvent */
+ sysEvent = 0;
+
+ code = (unsigned int)regs.r[0];
+
+ switch(code)
+ {
+ case 0: /* Null Event - drop out for standard processing*/
+ doPoll = 0;
+ break;
+
+ case 1: /* Redraw window */
+ _kernel_swi(Wimp_RedrawWindow, &regs,&regs);
+ if (message[0] == sdlWindow)
+ {
+ while (regs.r[0])
+ {
+ WIMP_PlotSprite(this, message[1], message[2]);
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ } else
+ {
+ /* TODO: Currently we just eat them - we may need to pass them on */
+ while (regs.r[0])
+ {
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ }
+ break;
+
+ case 2: /* Open window */
+ if ( resizeOnOpen && message[0] == sdlWindow)
+ {
+ /* Ensure window is correct size */
+ resizeOnOpen = 0;
+ message[3] = message[1] + (this->screen->w << this->hidden->xeig);
+ message[4] = message[2] + (this->screen->h << this->hidden->yeig);
+ }
+ _kernel_swi(Wimp_OpenWindow, &regs, &regs);
+ break;
+
+ case 3: /* Close window */
+ if (message[0] == sdlWindow)
+ {
+ /* Documentation makes it looks as if the following line is correct:
+ ** if (SDL_PrivateQuit() == 1) _kernel_swi(Wimp_CloseWindow, &regs, &regs);
+ ** However some programs don't process this message and so sit there invisibly
+ ** in the background so I just post the quit message and hope the application
+ ** does the correct thing.
+ */
+ SDL_PrivateQuit();
+ } else
+ sysEvent = 1;
+ doPoll = 0;
+ break;
+
+ case 4: /* Pointer_Leaving_Window */
+ if (message[0] == sdlWindow)
+ {
+ mouseInWindow = 0;
+ //TODO: Lose buttons / dragging
+ /* Reset to default pointer */
+ WIMP_RestoreWimpCursor();
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ } else
+ sysEvent = 1;
+ break;
+
+ case 5: /* Pointer_Entering_Window */
+ if (message[0] == sdlWindow)
+ {
+ mouseInWindow = 1;
+ WIMP_ReshowCursor(this);
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ } else sysEvent = 1;
+ break;
+
+ case 6: /* Mouse_Click */
+ if (hasFocus == 0)
+ {
+ /* First click gives focus if it's not a menu */
+ /* we only count non-menu clicks on a window that has the focus */
+ WIMP_SetFocus(message[3]);
+ } else
+ doPoll = 0; // So PollMouse gets a chance to pick it up
+ break;
+
+ case 7: /* User_Drag_Box - Used for mouse release */
+ //TODO: May need to implement this in the future
+ sysEvent = 1;
+ break;
+
+ case 8: /* Keypressed */
+ doPoll = 0; /* PollKeyboard should pick it up */
+ if (message[0] != sdlWindow) sysEvent = 1;
+ /*TODO: May want to always pass F12 etc to the wimp
+ {
+ regs.r[0] = message[6];
+ _kernel_swi(Wimp_ProcessKey, &regs, &regs);
+ }
+ */
+ break;
+
+ case 11: /* Lose Caret */
+ hasFocus = 0;
+ if (message[0] == sdlWindow) SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+ else sysEvent = 1;
+ break;
+
+ case 12: /* Gain Caret */
+ hasFocus = 1;
+ if (message[0] == sdlWindow) SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+ else sysEvent = 1;
+ break;
+
+ case 17:
+ case 18:
+ sysEvent = 1; /* All messages are passed on */
+
+ switch(message[4])
+ {
+ case 0: /* Quit Event */
+ /* No choice - have to quit */
+ SDL_Quit();
+ exit(0);
+ break;
+
+ case 8: /* Pre Quit */
+ SDL_PrivateQuit();
+ break;
+
+ case 0x400c1: /* Mode change */
+ WIMP_ModeChanged(this);
+ resizeOnOpen = 1;
+ break;
+
+ case 9: /* Palette changed */
+ WIMP_PaletteChanged(this);
+ break;
+ }
+ break;
+
+ default:
+ /* Pass unknown events on */
+ sysEvent = 1;
+ break;
+ }
+
+ if (sysEvent)
+ {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.eventCode = code;
+ SDL_memcpy(wmmsg.pollBlock, message, 64 * sizeof(int));
+
+ /* Fall out of polling loop if message is successfully posted */
+ if (SDL_PrivateSysWMEvent(&wmmsg)) doPoll = 0;
+ }
+#if !SDL_THREADS_DISABLED
+ if (riscos_using_threads)
+ {
+ /* Restart ticker here so other thread can not interfere
+ with the Redraw processing */
+ if (riscos_using_threads) __pthread_start_ticker();
+ /* Give other threads a better chance of running */
+ pthread_yield();
+ }
+#endif
+ }
+}
+
+/* Set focus to specified window */
+void WIMP_SetFocus(int win)
+{
+ _kernel_swi_regs regs;
+
+ regs.r[0] = win;
+ regs.r[1] = -1; /* Icon handle */
+ regs.r[2] = 0; /* X-offset we just put it at position 0 */
+ regs.r[3] = 0; /* Y-offset as above */
+ regs.r[4] = 1 << 25; /* Caret is invisible */
+ regs.r[5] = 0; /* index into string */
+
+ _kernel_swi(Wimp_SetCaretPosition, &regs, &regs);
+}
+
+/** Run background task while in a sleep command */
+void RISCOS_BackgroundTasks(void)
+{
+ if (current_video && current_video->hidden->window_handle)
+ {
+ WIMP_Poll(current_video, 0);
+ }
+#if SDL_THREADS_DISABLED
+ if (SDL_timer_running) RISCOS_CheckTimer();
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c
new file mode 100644
index 0000000..0f9c545
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/riscos/SDL_wimpvideo.c
@@ -0,0 +1,501 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ File added by Alan Buckley (alan_baa@hotmail.com) for RISC OS compatability
+ 27 March 2003
+
+ Implements RISC OS Wimp display.
+*/
+
+#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_riscostask.h"
+#include "SDL_riscosvideo.h"
+#include "SDL_riscosevents_c.h"
+#include "SDL_riscosmouse_c.h"
+
+#include "kernel.h"
+#include "swis.h"
+
+/* Initialization/Query functions */
+SDL_Rect **WIMP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+void WIMP_SetWMCaption(_THIS, const char *title, const char *icon);
+
+
+extern unsigned char *WIMP_CreateBuffer(int width, int height, int bpp);
+extern void WIMP_PumpEvents(_THIS);
+extern void WIMP_PlotSprite(_THIS, int x, int y);
+extern void WIMP_SetupPlotInfo(_THIS);
+extern void WIMP_SetFocus(int win);
+
+/* etc. */
+static void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+/* RISC OS Wimp handling helpers */
+void WIMP_ReadModeInfo(_THIS);
+unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface);
+void WIMP_SetDeviceMode(_THIS);
+void WIMP_DeleteWindow(_THIS);
+
+/* FULLSCREEN function required for wimp/fullscreen toggling */
+extern int FULLSCREEN_SetMode(int width, int height, int bpp);
+
+/* Currently need to set this up here as it only works if you
+ start up in a Wimp mode */
+extern int RISCOS_ToggleFullScreen(_THIS, int fullscreen);
+
+extern int riscos_backbuffer;
+extern int mouseInWindow;
+extern int riscos_closeaction;
+
+/* Following needed to ensure window is shown immediately */
+extern int hasFocus;
+extern void WIMP_Poll(_THIS, int waitTime);
+
+SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Uint32 Rmask = 0;
+ Uint32 Gmask = 0;
+ Uint32 Bmask = 0;
+ char *buffer = NULL;
+ int bytesPerPixel = 1;
+
+ /* Don't support double buffering in Wimp mode */
+ flags &= ~SDL_DOUBLEBUF;
+ flags &= ~SDL_HWSURFACE;
+
+ switch(bpp)
+ {
+ case 8:
+ /* Emulated palette using ColourTrans */
+ flags |= SDL_HWPALETTE;
+ break;
+
+ case 15:
+ case 16:
+ Bmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Rmask = 0x0000001f;
+ bytesPerPixel = 2;
+ break;
+
+ case 32:
+ Bmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Rmask = 0x000000ff;
+ bytesPerPixel = 4;
+ break;
+
+ default:
+ SDL_SetError("Pixel depth not supported");
+ return NULL;
+ break;
+ }
+
+/* printf("Setting mode %dx%d\n", width, height);*/
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->w = width;
+ this->hidden->height = current->h = height;
+
+ if (bpp == 15) bpp = 16;
+ buffer = WIMP_CreateBuffer(width, height, bpp);
+ if (buffer == NULL)
+ {
+ SDL_SetError("Couldn't create sprite for video memory");
+ return (NULL);
+ }
+
+ this->hidden->bank[0] = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->bank[1] = buffer; /* Start of buffer */
+
+ /* Remember sprite buffer so it can be freed later */
+ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank);
+ this->hidden->alloc_bank = buffer;
+
+ current->pitch = width * bytesPerPixel;
+ if ((current->pitch & 3))
+ {
+ /* Sprites are 32bit word aligned */
+ current->pitch += (4 - (current->pitch & 3));
+ }
+
+ current->flags = flags | SDL_PREALLOC;
+
+ WIMP_ReadModeInfo(this);
+
+ SDL_memset(this->hidden->bank[0], 0, height * current->pitch);
+
+ this->hidden->current_bank = 0;
+ current->pixels = this->hidden->bank[0];
+
+
+ if (WIMP_SetupWindow(this, current) == 0)
+ {
+ SDL_SetError("Unable to create window to display surface");
+ return NULL;
+ }
+
+ /* Reset device functions for the wimp */
+ WIMP_SetDeviceMode(this);
+
+ /* Needs to set up plot info after window has been created */
+ /* Not sure why, but plots don't work if I do it earlier */
+ WIMP_SetupPlotInfo(this);
+
+ /* Poll until window is shown */
+ {
+ /* We wait until it gets the focus, but give up after 5 seconds
+ in case the focus is prevented in any way.
+ */
+ Uint32 now = SDL_GetTicks();
+ while (!hasFocus && SDL_GetTicks() - now < 5000)
+ {
+ WIMP_Poll(this, 0);
+ }
+ }
+
+ /* We're done */
+ return(current);
+}
+
+
+void WIMP_ReadModeInfo(_THIS)
+{
+ _kernel_swi_regs regs;
+ int vars[6];
+ int vals[5];
+
+ vars[0] = 4; /* XEig */
+ vars[1] = 5; /* YEig */
+ vars[2] = 9; /* Log base 2 bpp */
+ vars[3] = 11; /* Screen Width - 1 */
+ vars[4] = 12; /* Screen Depth - 1 */
+ vars[5] = -1; /* Terminate list */
+
+ regs.r[0] = (int)vars;
+ regs.r[1] = (int)vals;
+ _kernel_swi(OS_ReadVduVariables, &regs, &regs);
+ this->hidden->xeig = vals[0];
+ this->hidden->yeig = vals[1];
+ this->hidden->screen_bpp = 1 << vals[2];
+ this->hidden->screen_width = vals[3] + 1;
+ this->hidden->screen_height = vals[4] + 1;
+}
+
+/* Set device function to call the correct versions for running
+ in a wimp window */
+
+void WIMP_SetDeviceMode(_THIS)
+{
+ if (this->UpdateRects == WIMP_UpdateRects) return; /* Already set up */
+
+ this->SetColors = WIMP_SetColors;
+ this->UpdateRects = WIMP_UpdateRects;
+
+ this->FlipHWSurface = NULL;
+
+ this->SetCaption = WIMP_SetWMCaption;
+ this->SetIcon = NULL;
+ this->IconifyWindow = NULL;
+
+ this->ShowWMCursor = WIMP_ShowWMCursor;
+ this->WarpWMCursor = WIMP_WarpWMCursor;
+
+ this->ToggleFullScreen = RISCOS_ToggleFullScreen;
+
+ this->PumpEvents = WIMP_PumpEvents;
+}
+
+/* Setup the Window to display the surface */
+unsigned int WIMP_SetupWindow(_THIS, SDL_Surface *surface)
+{
+ _kernel_swi_regs regs;
+ int window_data[23];
+ int *window_block = window_data+1;
+ int x = (this->hidden->screen_width - surface->w) / 2;
+ int y = (this->hidden->screen_height - surface->h) / 2;
+ int xeig = this->hidden->xeig;
+ int yeig = this->hidden->yeig;
+
+ mouseInWindow = 0;
+
+ /* Always delete the window and recreate on a change */
+ if (this->hidden->window_handle) WIMP_DeleteWindow(this);
+
+ /* Setup window co-ordinates */
+ window_block[0] = x << xeig;
+ window_block[1] = y << yeig;
+ window_block[2] = window_block[0] + (surface->w << xeig);
+ window_block[3] = window_block[1] + (surface->h << yeig);
+
+
+ window_block[4] = 0; /* Scroll offsets */
+ window_block[5] = 0;
+ window_block[6] = -1; /* Open on top of window stack */
+
+ window_block[7] = 0x85040042; /* Window flags */
+ if (riscos_closeaction != 0) window_block[7] |= 0x2000000;
+
+ /* TODO: Take into account surface->flags */
+
+ window_block[8] = 0xff070207; /* Window colours */
+ window_block[9] = 0x000c0103;
+ window_block[10] = 0; /* Work area minimum */
+ window_block[11] = -surface->h << yeig;
+ window_block[12] = surface->w << xeig; /* Work area maximum */
+ window_block[13] = 0;
+ window_block[14] = 0x2700013d; /* Title icon flags */
+ window_block[15] = 0x00003000; /* Work area flags - Mouse click down reported */
+ window_block[16] = 1; /* Sprite area control block pointer */
+ window_block[17] = 0x00100010; /* Minimum window size (width & height) (16x16)*/
+ window_block[18] = (int)this->hidden->title; /* Title data */
+ window_block[19] = -1;
+ window_block[20] = 256;
+ window_block[21] = 0; /* Number of icons */
+
+ regs.r[1] = (unsigned int)(window_block);
+
+ /* Create the window */
+ if (_kernel_swi(Wimp_CreateWindow, &regs, &regs) == NULL)
+ {
+ this->hidden->window_handle = window_data[0] = regs.r[0];
+
+ /* Show the window on the screen */
+ regs.r[1] = (unsigned int)window_data;
+ if (_kernel_swi(Wimp_OpenWindow, &regs, &regs) == NULL)
+ {
+ WIMP_SetFocus(this->hidden->window_handle);
+ } else
+ {
+ WIMP_DeleteWindow(this);
+ }
+ }
+
+ return this->hidden->window_handle;
+}
+
+/* Destroy the Window */
+
+void WIMP_DeleteWindow(_THIS)
+{
+ _kernel_swi_regs regs;
+ regs.r[1] = (unsigned int)&(this->hidden->window_handle);
+ _kernel_swi(Wimp_DeleteWindow, &regs, &regs);
+ this->hidden->window_handle = 0;
+}
+
+
+void WIMP_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ _kernel_swi_regs regs;
+ int update_block[12];
+ int xeig = this->hidden->xeig;
+ int yeig = this->hidden->yeig;
+ int j;
+ update_block[0] = this->hidden->window_handle;
+
+ for (j = 0; j < numrects; j++)
+ {
+ update_block[1] = rects[j].x << xeig; /* Min X */
+ update_block[4] = -(rects[j].y << yeig);
+ update_block[3] = update_block[1] + (rects[j].w << xeig);
+ update_block[2] = update_block[4] - (rects[j].h << yeig);
+
+ regs.r[1] = (int)update_block;
+ /* Update window can fail if called before first poll */
+ if (_kernel_swi(Wimp_UpdateWindow, &regs, &regs) == 0)
+ {
+ while (regs.r[0])
+ {
+ WIMP_PlotSprite(this, update_block[1], update_block[2]);
+ _kernel_swi(Wimp_GetRectangle, &regs, &regs);
+ }
+ }
+ }
+}
+
+
+int WIMP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ unsigned int *pal = (unsigned int *)(this->hidden->bank[1]+60);
+ int j;
+ SDL_Rect update;
+
+ pal += firstcolor*2;
+ for (j = 0; j < ncolors; j++)
+ {
+ *pal = (((unsigned int)colors->r) << 8)
+ + (((unsigned int)colors->g) << 16)
+ + (((unsigned int)colors->b) << 24);
+ pal[1] = *pal;
+ pal += 2;
+ colors++;
+ }
+
+ WIMP_SetupPlotInfo(this);
+
+ /* Need to refresh the window */
+ update.x = 0;
+ update.y = 0;
+ update.w = SDL_VideoSurface->w;
+ update.h = SDL_VideoSurface->h;
+ WIMP_UpdateRects(this, 1, &update);
+
+ return 1;
+}
+
+void WIMP_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+ _kernel_swi_regs regs;
+
+ SDL_strlcpy(this->hidden->title, title, SDL_arraysize(this->hidden->title));
+
+ if (RISCOS_GetWimpVersion() < 380)
+ {
+ int block[6];
+
+ regs.r[1] = (int)block;
+ _kernel_swi(Wimp_GetCaretPosition, &regs, &regs);
+ if (block[0] == (int)this->hidden->window_handle)
+ {
+ regs.r[0] = -1;
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ } else
+ {
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = -1;
+ regs.r[2] = -1;
+ regs.r[3] = -1;
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ }
+ regs.r[0] = block[0];
+ regs.r[1] = block[1];
+ regs.r[2] = block[2];
+ regs.r[3] = block[3];
+ regs.r[4] = block[4];
+ regs.r[5] = block[5];
+ _kernel_swi(Wimp_SetCaretPosition, &regs,&regs);
+ } else
+ {
+ regs.r[0] = this->hidden->window_handle;
+ regs.r[1] = 0x4b534154; /* "TASK" */
+ regs.r[2] = 3; /* Redraw title */
+ _kernel_swi(Wimp_ForceRedraw, &regs, &regs);
+ }
+}
+
+void WIMP_RefreshDesktop(_THIS)
+{
+ int width = this->hidden->screen_width << this->hidden->xeig;
+ int height = this->hidden->screen_height << this->hidden->yeig;
+ _kernel_swi_regs regs;
+ regs.r[0] = -1; /* Whole screen */
+ regs.r[1] = 0;
+ regs.r[2] = 0;
+ regs.r[3] = width;
+ regs.r[4] = height;
+ _kernel_swi(Wimp_ForceRedraw, &regs, &regs);
+}
+
+/* Toggle to window from full screen */
+int WIMP_ToggleFromFullScreen(_THIS)
+{
+ int width = this->screen->w;
+ int height = this->screen->h;
+ int bpp = this->screen->format->BitsPerPixel;
+ char *buffer = NULL;
+ char *old_bank[2];
+ char *old_alloc_bank;
+
+ /* Ensure flags are OK */
+ this->screen->flags &= ~(SDL_DOUBLEBUF|SDL_HWSURFACE);
+
+ if (this->hidden->bank[0] == this->hidden->alloc_bank || riscos_backbuffer == 0)
+ {
+ /* Need to create a sprite for the screen and copy the data to it */
+ char *data;
+ buffer = WIMP_CreateBuffer(width, height, bpp);
+ data = buffer + 60; /* Start of sprite data */
+ if (bpp == 8) data += 2048; /* 8bpp sprite have palette first */
+
+ if (buffer == NULL) return 0;
+ SDL_memcpy(data, this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel);
+ }
+ /* else We've switch to full screen before so we already have a sprite */
+
+ old_bank[0] = this->hidden->bank[0];
+ old_bank[1] = this->hidden->bank[1];
+ old_alloc_bank = this->hidden->alloc_bank;
+
+ if (buffer != NULL) this->hidden->alloc_bank = buffer;
+
+ this->hidden->bank[1] = this->hidden->alloc_bank;
+ this->hidden->bank[0] = this->hidden->bank[1] + 60; /* Start of sprite data */
+ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */
+
+ this->hidden->current_bank = 0;
+ this->screen->pixels = this->hidden->bank[0];
+
+ RISCOS_RestoreWimpMode();
+ WIMP_ReadModeInfo(this);
+ if (WIMP_SetupWindow(this, this->screen))
+ {
+ WIMP_SetDeviceMode(this);
+ WIMP_SetupPlotInfo(this);
+
+ if (riscos_backbuffer == 0) riscos_backbuffer = 1;
+
+ if (buffer && old_alloc_bank) SDL_free(old_alloc_bank);
+
+ return 1;
+ } else
+ {
+ /* Drop back to full screen mode on failure */
+ this->hidden->bank[0] = old_bank[0];
+ this->hidden->bank[1] = old_bank[1];
+ this->hidden->alloc_bank = old_alloc_bank;
+ if (buffer) SDL_free(buffer);
+
+ RISCOS_StoreWimpMode();
+ FULLSCREEN_SetMode(width, height, bpp);
+ }
+
+ return 0;
+}
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents.c b/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents.c
new file mode 100644
index 0000000..107a702
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents.c
@@ -0,0 +1,412 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting X11 events into SDL events */
+
+#include <vga.h>
+#include <vgamouse.h>
+#include <vgakeyboard.h>
+#if defined(__LINUX__)
+#include <linux/kd.h>
+#include <linux/keyboard.h>
+#elif defined(__FREEBSD__)
+#include <sys/kbio.h>
+#else
+#error You must choose your operating system here
+#endif
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_svgavideo.h"
+#include "SDL_svgaevents_c.h"
+
+/* The translation tables from a console scancode to a SDL keysym */
+#if defined(linux)
+#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
+static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS];
+#elif defined(__FREEBSD__)
+/* FIXME: Free the keymap when we shut down the video mode */
+static keymap_t *vga_keymap = NULL;
+#else
+#error You must choose your operating system here
+#endif
+static SDLKey keymap[128];
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
+
+/* Ugh, we have to duplicate the kernel's keysym mapping code...
+ Oh, it's not so bad. :-)
+
+ FIXME: Add keyboard LED handling code
+ */
+#if defined(linux)
+int SVGA_initkeymaps(int fd)
+{
+ struct kbentry entry;
+ int map, i;
+
+ /* Load all the keysym mappings */
+ for ( map=0; map<NUM_VGAKEYMAPS; ++map ) {
+ SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16));
+ for ( i=0; i<NR_KEYS; ++i ) {
+ entry.kb_table = map;
+ entry.kb_index = i;
+ if ( ioctl(fd, KDGKBENT, &entry) == 0 ) {
+ /* The "Enter" key is a special case */
+ if ( entry.kb_value == K_ENTER ) {
+ entry.kb_value = K(KT_ASCII,13);
+ }
+ /* Handle numpad specially as well */
+ if ( KTYP(entry.kb_value) == KT_PAD ) {
+ switch ( entry.kb_value ) {
+ case K_P0:
+ case K_P1:
+ case K_P2:
+ case K_P3:
+ case K_P4:
+ case K_P5:
+ case K_P6:
+ case K_P7:
+ case K_P8:
+ case K_P9:
+ vga_keymap[map][i]=entry.kb_value;
+ vga_keymap[map][i]+= '0';
+ break;
+ case K_PPLUS:
+ vga_keymap[map][i]=K(KT_ASCII,'+');
+ break;
+ case K_PMINUS:
+ vga_keymap[map][i]=K(KT_ASCII,'-');
+ break;
+ case K_PSTAR:
+ vga_keymap[map][i]=K(KT_ASCII,'*');
+ break;
+ case K_PSLASH:
+ vga_keymap[map][i]=K(KT_ASCII,'/');
+ break;
+ case K_PENTER:
+ vga_keymap[map][i]=K(KT_ASCII,'\r');
+ break;
+ case K_PCOMMA:
+ vga_keymap[map][i]=K(KT_ASCII,',');
+ break;
+ case K_PDOT:
+ vga_keymap[map][i]=K(KT_ASCII,'.');
+ break;
+ default:
+ break;
+ }
+ }
+ /* Do the normal key translation */
+ if ( (KTYP(entry.kb_value) == KT_LATIN) ||
+ (KTYP(entry.kb_value) == KT_ASCII) ||
+ (KTYP(entry.kb_value) == KT_LETTER) ) {
+ vga_keymap[map][i] = entry.kb_value;
+ }
+ }
+ }
+ }
+ return(0);
+}
+#elif defined(__FREEBSD__)
+int SVGA_initkeymaps(int fd)
+{
+ vga_keymap = SDL_malloc(sizeof(keymap_t));
+ if ( ! vga_keymap ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ if (ioctl(fd, GIO_KEYMAP, vga_keymap) == -1) {
+ SDL_free(vga_keymap);
+ vga_keymap = NULL;
+ SDL_SetError("Unable to get keyboard map");
+ return(-1);
+ }
+ return(0);
+}
+#else
+#error You must choose your operating system here
+#endif
+
+int posted = 0;
+
+void SVGA_mousecallback(int button, int dx, int dy,
+ int u1,int u2,int u3, int u4)
+{
+ if ( dx || dy ) {
+ posted += SDL_PrivateMouseMotion(0, 1, dx, dy);
+ }
+ if ( button & MOUSE_LEFTBUTTON ) {
+ if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 1, 0, 0);
+ }
+ } else {
+ if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 1, 0, 0);
+ }
+ }
+ if ( button & MOUSE_MIDDLEBUTTON ) {
+ if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 2, 0, 0);
+ }
+ } else {
+ if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 2, 0, 0);
+ }
+ }
+ if ( button & MOUSE_RIGHTBUTTON ) {
+ if ( !(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3)) ) {
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, 3, 0, 0);
+ }
+ } else {
+ if ( (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(3)) ) {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, 3, 0, 0);
+ }
+ }
+}
+
+void SVGA_keyboardcallback(int scancode, int pressed)
+{
+ SDL_keysym keysym;
+
+ if ( pressed ) {
+ posted += SDL_PrivateKeyboard(SDL_PRESSED,
+ TranslateKey(scancode, &keysym));
+ } else {
+ posted += SDL_PrivateKeyboard(SDL_RELEASED,
+ TranslateKey(scancode, &keysym));
+ }
+}
+
+void SVGA_PumpEvents(_THIS)
+{
+ do {
+ posted = 0;
+ mouse_update();
+ keyboard_update();
+ } while ( posted );
+}
+
+void SVGA_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the BeOS key translation table */
+ for ( i=0; i<SDL_arraysize(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[SCANCODE_ESCAPE] = SDLK_ESCAPE;
+ keymap[SCANCODE_1] = SDLK_1;
+ keymap[SCANCODE_2] = SDLK_2;
+ keymap[SCANCODE_3] = SDLK_3;
+ keymap[SCANCODE_4] = SDLK_4;
+ keymap[SCANCODE_5] = SDLK_5;
+ keymap[SCANCODE_6] = SDLK_6;
+ keymap[SCANCODE_7] = SDLK_7;
+ keymap[SCANCODE_8] = SDLK_8;
+ keymap[SCANCODE_9] = SDLK_9;
+ keymap[SCANCODE_0] = SDLK_0;
+ keymap[SCANCODE_MINUS] = SDLK_MINUS;
+ keymap[SCANCODE_EQUAL] = SDLK_EQUALS;
+ keymap[SCANCODE_BACKSPACE] = SDLK_BACKSPACE;
+ keymap[SCANCODE_TAB] = SDLK_TAB;
+ keymap[SCANCODE_Q] = SDLK_q;
+ keymap[SCANCODE_W] = SDLK_w;
+ keymap[SCANCODE_E] = SDLK_e;
+ keymap[SCANCODE_R] = SDLK_r;
+ keymap[SCANCODE_T] = SDLK_t;
+ keymap[SCANCODE_Y] = SDLK_y;
+ keymap[SCANCODE_U] = SDLK_u;
+ keymap[SCANCODE_I] = SDLK_i;
+ keymap[SCANCODE_O] = SDLK_o;
+ keymap[SCANCODE_P] = SDLK_p;
+ keymap[SCANCODE_BRACKET_LEFT] = SDLK_LEFTBRACKET;
+ keymap[SCANCODE_BRACKET_RIGHT] = SDLK_RIGHTBRACKET;
+ keymap[SCANCODE_ENTER] = SDLK_RETURN;
+ keymap[SCANCODE_LEFTCONTROL] = SDLK_LCTRL;
+ keymap[SCANCODE_A] = SDLK_a;
+ keymap[SCANCODE_S] = SDLK_s;
+ keymap[SCANCODE_D] = SDLK_d;
+ keymap[SCANCODE_F] = SDLK_f;
+ keymap[SCANCODE_G] = SDLK_g;
+ keymap[SCANCODE_H] = SDLK_h;
+ keymap[SCANCODE_J] = SDLK_j;
+ keymap[SCANCODE_K] = SDLK_k;
+ keymap[SCANCODE_L] = SDLK_l;
+ keymap[SCANCODE_SEMICOLON] = SDLK_SEMICOLON;
+ keymap[SCANCODE_APOSTROPHE] = SDLK_QUOTE;
+ keymap[SCANCODE_GRAVE] = SDLK_BACKQUOTE;
+ keymap[SCANCODE_LEFTSHIFT] = SDLK_LSHIFT;
+ keymap[SCANCODE_BACKSLASH] = SDLK_BACKSLASH;
+ keymap[SCANCODE_Z] = SDLK_z;
+ keymap[SCANCODE_X] = SDLK_x;
+ keymap[SCANCODE_C] = SDLK_c;
+ keymap[SCANCODE_V] = SDLK_v;
+ keymap[SCANCODE_B] = SDLK_b;
+ keymap[SCANCODE_N] = SDLK_n;
+ keymap[SCANCODE_M] = SDLK_m;
+ keymap[SCANCODE_COMMA] = SDLK_COMMA;
+ keymap[SCANCODE_PERIOD] = SDLK_PERIOD;
+ keymap[SCANCODE_SLASH] = SDLK_SLASH;
+ keymap[SCANCODE_RIGHTSHIFT] = SDLK_RSHIFT;
+ keymap[SCANCODE_KEYPADMULTIPLY] = SDLK_KP_MULTIPLY;
+ keymap[SCANCODE_LEFTALT] = SDLK_LALT;
+ keymap[SCANCODE_SPACE] = SDLK_SPACE;
+ keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK;
+ keymap[SCANCODE_F1] = SDLK_F1;
+ keymap[SCANCODE_F2] = SDLK_F2;
+ keymap[SCANCODE_F3] = SDLK_F3;
+ keymap[SCANCODE_F4] = SDLK_F4;
+ keymap[SCANCODE_F5] = SDLK_F5;
+ keymap[SCANCODE_F6] = SDLK_F6;
+ keymap[SCANCODE_F7] = SDLK_F7;
+ keymap[SCANCODE_F8] = SDLK_F8;
+ keymap[SCANCODE_F9] = SDLK_F9;
+ keymap[SCANCODE_F10] = SDLK_F10;
+ keymap[SCANCODE_NUMLOCK] = SDLK_NUMLOCK;
+ keymap[SCANCODE_SCROLLLOCK] = SDLK_SCROLLOCK;
+ keymap[SCANCODE_KEYPAD7] = SDLK_KP7;
+ keymap[SCANCODE_CURSORUPLEFT] = SDLK_KP7;
+ keymap[SCANCODE_KEYPAD8] = SDLK_KP8;
+ keymap[SCANCODE_CURSORUP] = SDLK_KP8;
+ keymap[SCANCODE_KEYPAD9] = SDLK_KP9;
+ keymap[SCANCODE_CURSORUPRIGHT] = SDLK_KP9;
+ keymap[SCANCODE_KEYPADMINUS] = SDLK_KP_MINUS;
+ keymap[SCANCODE_KEYPAD4] = SDLK_KP4;
+ keymap[SCANCODE_CURSORLEFT] = SDLK_KP4;
+ keymap[SCANCODE_KEYPAD5] = SDLK_KP5;
+ keymap[SCANCODE_KEYPAD6] = SDLK_KP6;
+ keymap[SCANCODE_CURSORRIGHT] = SDLK_KP6;
+ keymap[SCANCODE_KEYPADPLUS] = SDLK_KP_PLUS;
+ keymap[SCANCODE_KEYPAD1] = SDLK_KP1;
+ keymap[SCANCODE_CURSORDOWNLEFT] = SDLK_KP1;
+ keymap[SCANCODE_KEYPAD2] = SDLK_KP2;
+ keymap[SCANCODE_CURSORDOWN] = SDLK_KP2;
+ keymap[SCANCODE_KEYPAD3] = SDLK_KP3;
+ keymap[SCANCODE_CURSORDOWNRIGHT] = SDLK_KP3;
+ keymap[SCANCODE_KEYPAD0] = SDLK_KP0;
+ keymap[SCANCODE_KEYPADPERIOD] = SDLK_KP_PERIOD;
+ keymap[SCANCODE_LESS] = SDLK_LESS;
+ keymap[SCANCODE_F11] = SDLK_F11;
+ keymap[SCANCODE_F12] = SDLK_F12;
+ keymap[SCANCODE_KEYPADENTER] = SDLK_KP_ENTER;
+ keymap[SCANCODE_RIGHTCONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_CONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_KEYPADDIVIDE] = SDLK_KP_DIVIDE;
+ keymap[SCANCODE_PRINTSCREEN] = SDLK_PRINT;
+ keymap[SCANCODE_RIGHTALT] = SDLK_RALT;
+ keymap[SCANCODE_BREAK] = SDLK_BREAK;
+ keymap[SCANCODE_BREAK_ALTERNATIVE] = SDLK_UNKNOWN;
+ keymap[SCANCODE_HOME] = SDLK_HOME;
+ keymap[SCANCODE_CURSORBLOCKUP] = SDLK_UP;
+ keymap[SCANCODE_PAGEUP] = SDLK_PAGEUP;
+ keymap[SCANCODE_CURSORBLOCKLEFT] = SDLK_LEFT;
+ keymap[SCANCODE_CURSORBLOCKRIGHT] = SDLK_RIGHT;
+ keymap[SCANCODE_END] = SDLK_END;
+ keymap[SCANCODE_CURSORBLOCKDOWN] = SDLK_DOWN;
+ keymap[SCANCODE_PAGEDOWN] = SDLK_PAGEDOWN;
+ keymap[SCANCODE_INSERT] = SDLK_INSERT;
+ keymap[SCANCODE_REMOVE] = SDLK_DELETE;
+ keymap[119] = SDLK_PAUSE;
+ keymap[SCANCODE_RIGHTWIN] = SDLK_RSUPER;
+ keymap[SCANCODE_LEFTWIN] = SDLK_LSUPER;
+ keymap[127] = SDLK_MENU;
+}
+
+#if defined(linux)
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE ) {
+ int map;
+ SDLMod modstate;
+
+ modstate = SDL_GetModState();
+ map = 0;
+ if ( modstate & KMOD_SHIFT ) {
+ map |= (1<<KG_SHIFT);
+ }
+ if ( modstate & KMOD_CTRL ) {
+ map |= (1<<KG_CTRL);
+ }
+ if ( modstate & KMOD_ALT ) {
+ map |= (1<<KG_ALT);
+ }
+ if ( modstate & KMOD_MODE ) {
+ map |= (1<<KG_ALTGR);
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) {
+ if ( modstate & KMOD_CAPS ) {
+ map ^= (1<<KG_SHIFT);
+ }
+ }
+ if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) {
+ if ( modstate & KMOD_NUM ) {
+ keysym->unicode=KVAL(vga_keymap[map][scancode]);
+ }
+ } else {
+ keysym->unicode = KVAL(vga_keymap[map][scancode]);
+ }
+ }
+ return(keysym);
+}
+#elif defined(__FREEBSD__)
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE && vga_keymap ) {
+ int map;
+ SDLMod modstate;
+
+ modstate = SDL_GetModState();
+ map = 0;
+ if ( modstate & KMOD_SHIFT ) {
+ map += 1;
+ }
+ if ( modstate & KMOD_CTRL ) {
+ map += 2;
+ }
+ if ( modstate & KMOD_ALT ) {
+ map += 4;
+ }
+ if ( !(vga_keymap->key[scancode].spcl & (0x80 >> map)) ) {
+ keysym->unicode = vga_keymap->key[scancode].map[map];
+ }
+
+ }
+ return(keysym);
+}
+#else
+#error You must choose your operating system here
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents_c.h b/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents_c.h
new file mode 100644
index 0000000..cd9f888
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgaevents_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_svgavideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern int SVGA_initkeymaps(int fd);
+extern void SVGA_mousecallback(int button, int dx, int dy,
+ int u1,int u2,int u3, int u4);
+extern void SVGA_keyboardcallback(int scancode, int pressed);
+
+extern void SVGA_InitOSKeymap(_THIS);
+extern void SVGA_PumpEvents(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse.c b/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse.c
new file mode 100644
index 0000000..a82dbfd
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse.c
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_svgavideo.h"
+#include "SDL_svgamouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse_c.h b/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse_c.h
new file mode 100644
index 0000000..78fe8ab
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgamouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_svgavideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.c b/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.c
new file mode 100644
index 0000000..58ea800
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.c
@@ -0,0 +1,584 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* SVGAlib based SDL video driver implementation.
+*/
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+
+#if defined(__LINUX__)
+#include <linux/vt.h>
+#elif defined(__FREEBSD__)
+#include <sys/consio.h>
+#else
+#error You must choose your operating system here
+#endif
+#include <vga.h>
+#include <vgamouse.h>
+#include <vgakeyboard.h>
+
+#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_svgavideo.h"
+#include "SDL_svgaevents_c.h"
+#include "SDL_svgamouse_c.h"
+
+/* Initialization/Query functions */
+static int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int SVGA_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void SVGA_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int SVGA_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int SVGA_LockHWSurface(_THIS, SDL_Surface *surface);
+static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void SVGA_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void SVGA_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* SVGAlib driver bootstrap functions */
+
+static int SVGA_Available(void)
+{
+ /* Check to see if we are root and stdin is a virtual console */
+ int console;
+
+ /* SVGALib 1.9.x+ doesn't require root (via /dev/svga) */
+ int svgalib2 = -1;
+
+ /* See if we are connected to a virtual terminal */
+ console = STDIN_FILENO;
+#if 0 /* This is no longer needed, SVGAlib can switch consoles for us */
+ if ( console >= 0 ) {
+ struct stat sb;
+ struct vt_mode dummy;
+
+ if ( (fstat(console, &sb) < 0) ||
+ (ioctl(console, VT_GETMODE, &dummy) < 0) ) {
+ console = -1;
+ }
+ }
+#endif /* 0 */
+
+ /* See if SVGAlib 2.0 is available */
+ svgalib2 = open("/dev/svga", O_RDONLY);
+ if (svgalib2 != -1) {
+ close(svgalib2);
+ }
+
+ return(((svgalib2 != -1) || (geteuid() == 0)) && (console >= 0));
+}
+
+static void SVGA_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *SVGA_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = SVGA_VideoInit;
+ device->ListModes = SVGA_ListModes;
+ device->SetVideoMode = SVGA_SetVideoMode;
+ device->SetColors = SVGA_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = SVGA_VideoQuit;
+ device->AllocHWSurface = SVGA_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = SVGA_LockHWSurface;
+ device->UnlockHWSurface = SVGA_UnlockHWSurface;
+ device->FlipHWSurface = SVGA_FlipHWSurface;
+ device->FreeHWSurface = SVGA_FreeHWSurface;
+ device->SetCaption = NULL;
+ device->SetIcon = NULL;
+ device->IconifyWindow = NULL;
+ device->GrabInput = NULL;
+ device->GetWMInfo = NULL;
+ device->InitOSKeymap = SVGA_InitOSKeymap;
+ device->PumpEvents = SVGA_PumpEvents;
+
+ device->free = SVGA_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap SVGALIB_bootstrap = {
+ "svgalib", "SVGAlib",
+ SVGA_Available, SVGA_CreateDevice
+};
+
+static int SVGA_AddMode(_THIS, int mode, int actually_add)
+{
+ int i, j;
+ vga_modeinfo *modeinfo;
+
+ modeinfo = vga_getmodeinfo(mode);
+
+ i = modeinfo->bytesperpixel-1;
+ if ( i < 0 ) {
+ return 0;
+ }
+ if ( actually_add ) {
+ SDL_Rect saved_rect[2];
+ int saved_mode[2];
+ int b;
+
+ /* Add the mode, sorted largest to smallest */
+ b = 0;
+ j = 0;
+ while ( (SDL_modelist[i][j]->w > modeinfo->width) ||
+ (SDL_modelist[i][j]->h > modeinfo->height) ) {
+ ++j;
+ }
+ /* Skip modes that are already in our list */
+ if ( (SDL_modelist[i][j]->w == modeinfo->width) &&
+ (SDL_modelist[i][j]->h == modeinfo->height) ) {
+ return(0);
+ }
+ /* Insert the new mode */
+ saved_rect[b] = *SDL_modelist[i][j];
+ saved_mode[b] = SDL_vgamode[i][j];
+ SDL_modelist[i][j]->w = modeinfo->width;
+ SDL_modelist[i][j]->h = modeinfo->height;
+ SDL_vgamode[i][j] = mode;
+ /* Everybody scoot down! */
+ if ( saved_rect[b].w && saved_rect[b].h ) {
+ for ( ++j; SDL_modelist[i][j]->w; ++j ) {
+ saved_rect[!b] = *SDL_modelist[i][j];
+ saved_mode[!b] = SDL_vgamode[i][j];
+ *SDL_modelist[i][j] = saved_rect[b];
+ SDL_vgamode[i][j] = saved_mode[b];
+ b = !b;
+ }
+ *SDL_modelist[i][j] = saved_rect[b];
+ SDL_vgamode[i][j] = saved_mode[b];
+ }
+ } else {
+ ++SDL_nummodes[i];
+ }
+ return(1);
+}
+
+static void SVGA_UpdateVideoInfo(_THIS)
+{
+ vga_modeinfo *modeinfo;
+
+ this->info.wm_available = 0;
+ this->info.hw_available = (banked ? 0 : 1);
+ modeinfo = vga_getmodeinfo(vga_getcurrentmode());
+ this->info.video_mem = modeinfo->memory;
+ /* FIXME: Add hardware accelerated blit information */
+#ifdef SVGALIB_DEBUG
+ printf("Hardware accelerated blit: %savailable\n", modeinfo->haveblit ? "" : "not ");
+#endif
+}
+
+int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int keyboard;
+ int i, j;
+ int mode, total_modes;
+
+ /* Initialize all variables that we clean on shutdown */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_nummodes[i] = 0;
+ SDL_modelist[i] = NULL;
+ SDL_vgamode[i] = NULL;
+ }
+
+ /* Initialize the library */
+ vga_disabledriverreport();
+ if ( vga_init() < 0 ) {
+ SDL_SetError("Unable to initialize SVGAlib");
+ return(-1);
+ }
+ vga_setmode(TEXT);
+
+ /* Enable mouse and keyboard support */
+ vga_setmousesupport(1);
+ keyboard = keyboard_init_return_fd();
+ if ( keyboard < 0 ) {
+ SDL_SetError("Unable to initialize keyboard");
+ return(-1);
+ }
+ if ( SVGA_initkeymaps(keyboard) < 0 ) {
+ return(-1);
+ }
+ keyboard_seteventhandler(SVGA_keyboardcallback);
+
+ /* Determine the current screen size */
+ this->info.current_w = 0;
+ this->info.current_h = 0;
+
+ /* Determine the screen depth (use default 8-bit depth) */
+ vformat->BitsPerPixel = 8;
+
+ /* Enumerate the available fullscreen modes */
+ total_modes = 0;
+ for ( mode=vga_lastmodenumber(); mode; --mode ) {
+ if ( vga_hasmode(mode) ) {
+ if ( SVGA_AddMode(this, mode, 0) ) {
+ ++total_modes;
+ }
+ }
+ }
+ if ( SVGA_AddMode(this, G320x200x256, 0) ) ++total_modes;
+ if ( total_modes == 0 ) {
+ SDL_SetError("No linear video modes available");
+ return(-1);
+ }
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_vgamode[i] = (int *)SDL_malloc(SDL_nummodes[i]*sizeof(int));
+ if ( SDL_vgamode[i] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ SDL_modelist[i] = (SDL_Rect **)
+ SDL_malloc((SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[i] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ for ( j=0; j<SDL_nummodes[i]; ++j ) {
+ SDL_modelist[i][j]=(SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[i][j] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ SDL_memset(SDL_modelist[i][j], 0, sizeof(SDL_Rect));
+ }
+ SDL_modelist[i][j] = NULL;
+ }
+ for ( mode=vga_lastmodenumber(); mode; --mode ) {
+ if ( vga_hasmode(mode) ) {
+ SVGA_AddMode(this, mode, 1);
+ }
+ }
+ SVGA_AddMode(this, G320x200x256, 1);
+
+ /* Free extra (duplicated) modes */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ j = 0;
+ while ( SDL_modelist[i][j] && SDL_modelist[i][j]->w ) {
+ j++;
+ }
+ while ( SDL_modelist[i][j] ) {
+ SDL_free(SDL_modelist[i][j]);
+ SDL_modelist[i][j] = NULL;
+ j++;
+ }
+ }
+
+ /* Fill in our hardware acceleration capabilities */
+ SVGA_UpdateVideoInfo(this);
+
+ /* We're done! */
+ return(0);
+}
+
+SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+}
+
+/* Various screen update functions available */
+static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ int mode;
+ int vgamode;
+ vga_modeinfo *modeinfo;
+ int screenpage_len;
+
+ /* Free old pixels if we were in banked mode */
+ if ( banked && current->pixels ) {
+ free(current->pixels);
+ current->pixels = NULL;
+ }
+
+ /* Try to set the requested linear video mode */
+ bpp = (bpp+7)/8-1;
+ for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) {
+ if ( (SDL_modelist[bpp][mode]->w == width) &&
+ (SDL_modelist[bpp][mode]->h == height) ) {
+ break;
+ }
+ }
+ if ( SDL_modelist[bpp][mode] == NULL ) {
+ SDL_SetError("Couldn't find requested mode in list");
+ return(NULL);
+ }
+ vgamode = SDL_vgamode[bpp][mode];
+ vga_setmode(vgamode);
+ vga_setpage(0);
+
+ if ( (vga_setlinearaddressing() < 0) && (vgamode != G320x200x256) ) {
+ banked = 1;
+ } else {
+ banked = 0;
+ }
+
+ modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]);
+
+ /* Update hardware acceleration info */
+ SVGA_UpdateVideoInfo(this);
+
+ /* Allocate the new pixel format for the screen */
+ bpp = (bpp+1)*8;
+ if ( (bpp == 16) && (modeinfo->colors == 32768) ) {
+ bpp = 15;
+ }
+ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ current->flags = SDL_FULLSCREEN;
+ if ( !banked ) {
+ current->flags |= SDL_HWSURFACE;
+ }
+ if ( bpp == 8 ) {
+ /* FIXME: What about DirectColor? */
+ current->flags |= SDL_HWPALETTE;
+ }
+ current->w = width;
+ current->h = height;
+ current->pitch = modeinfo->linewidth;
+ if ( banked ) {
+ current->pixels = SDL_malloc(current->h * current->pitch);
+ if ( !current->pixels ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ } else {
+ current->pixels = vga_getgraphmem();
+ }
+
+ /* set double-buffering */
+ if ( (flags & SDL_DOUBLEBUF) && !banked )
+ {
+ /* length of one screen page in bytes */
+ screenpage_len=current->h*modeinfo->linewidth;
+
+ /* if start address should be aligned */
+ if ( modeinfo->linewidth_unit )
+ {
+ if ( screenpage_len % modeinfo->linewidth_unit )
+ {
+ screenpage_len += modeinfo->linewidth_unit - ( screenpage_len % modeinfo->linewidth_unit );
+ }
+ }
+
+ /* if we heve enough videomemory = ak je dost videopamete */
+ if ( modeinfo->memory > ( screenpage_len * 2 / 1024 ) )
+ {
+ current->flags |= SDL_DOUBLEBUF;
+ flip_page = 0;
+ flip_offset[0] = 0;
+ flip_offset[1] = screenpage_len;
+ flip_address[0] = vga_getgraphmem();
+ flip_address[1] = flip_address[0]+screenpage_len;
+ SVGA_FlipHWSurface(this,current);
+ }
+ }
+
+ /* Set the blit function */
+ if ( banked ) {
+ this->UpdateRects = SVGA_BankedUpdate;
+ } else {
+ this->UpdateRects = SVGA_DirectUpdate;
+ }
+
+ /* Set up the mouse handler again (buggy SVGAlib 1.40) */
+ mouse_seteventhandler(SVGA_mousecallback);
+
+ /* We're done */
+ return(current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int SVGA_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void SVGA_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int SVGA_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ /* The waiting is done in SVGA_FlipHWSurface() */
+ return(0);
+}
+static void SVGA_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( !banked ) {
+ vga_setdisplaystart(flip_offset[flip_page]);
+ flip_page=!flip_page;
+ surface->pixels=flip_address[flip_page];
+ vga_waitretrace();
+ }
+ return(0);
+}
+
+static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ return;
+}
+
+static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i, j;
+ SDL_Rect *rect;
+ int page, vp;
+ int x, y, w, h;
+ unsigned char *src;
+ unsigned char *dst;
+ int bpp = this->screen->format->BytesPerPixel;
+ int pitch = this->screen->pitch;
+
+ dst = vga_getgraphmem();
+ for ( i=0; i < numrects; ++i ) {
+ rect = &rects[i];
+ x = rect->x;
+ y = rect->y;
+ w = rect->w * bpp;
+ h = rect->h;
+
+ vp = y * pitch + x * bpp;
+ src = (unsigned char *)this->screen->pixels + vp;
+ page = vp >> 16;
+ vp &= 0xffff;
+ vga_setpage(page);
+ for (j = 0; j < h; j++) {
+ if (vp + w > 0x10000) {
+ if (vp >= 0x10000) {
+ page++;
+ vga_setpage(page);
+ vp &= 0xffff;
+ } else {
+ SDL_memcpy(dst + vp, src, 0x10000 - vp);
+ page++;
+ vga_setpage(page);
+ SDL_memcpy(dst, src + 0x10000 - vp,
+ (vp + w) & 0xffff);
+ vp = (vp + pitch) & 0xffff;
+ src += pitch;
+ continue;
+ }
+ }
+ SDL_memcpy(dst + vp, src, w);
+ src += pitch;
+ vp += pitch;
+ }
+ }
+}
+
+int SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+
+ for(i = 0; i < ncolors; i++) {
+ vga_setpalette(firstcolor + i,
+ colors[i].r>>2,
+ colors[i].g>>2,
+ colors[i].b>>2);
+ }
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void SVGA_VideoQuit(_THIS)
+{
+ int i, j;
+
+ /* Reset the console video mode */
+ if ( this->screen && (this->screen->w && this->screen->h) ) {
+ vga_setmode(TEXT);
+ }
+ keyboard_close();
+
+ /* Free video mode lists */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ for ( j=0; SDL_modelist[i][j]; ++j )
+ SDL_free(SDL_modelist[i][j]);
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ if ( SDL_vgamode[i] != NULL ) {
+ SDL_free(SDL_vgamode[i]);
+ SDL_vgamode[i] = NULL;
+ }
+ }
+ if ( this->screen ) {
+ if ( banked && this->screen->pixels ) {
+ SDL_free(this->screen->pixels);
+ }
+ this->screen->pixels = NULL;
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.h b/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.h
new file mode 100644
index 0000000..7fb86cb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/svga/SDL_svgavideo.h
@@ -0,0 +1,58 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_svgavideo_h
+#define _SDL_svgavideo_h
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ int *SDL_vgamode[NUM_MODELISTS];
+
+ /* information for double-buffering */
+ int flip_page;
+ int flip_offset[2];
+ Uint8 *flip_address[2];
+
+ /* Set to 1 if we're in banked video mode */
+ int banked;
+};
+/* Old variable names */
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define SDL_vgamode (this->hidden->SDL_vgamode)
+#define flip_page (this->hidden->flip_page)
+#define flip_offset (this->hidden->flip_offset)
+#define flip_address (this->hidden->flip_address)
+#define banked (this->hidden->banked)
+
+#endif /* _SDL_svgavideo_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocevents.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocevents.cpp
new file mode 100644
index 0000000..5ceed5f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocevents.cpp
@@ -0,0 +1,626 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+/*
+ SDL_epocevents.cpp
+ Handle the event stream, converting Epoc events into SDL events
+
+ Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
+*/
+
+
+#include <stdio.h>
+#undef NULL
+extern "C" {
+//#define DEBUG_TRACE_ENABLED
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_keysym.h"
+#include "SDL_keyboard.h"
+#include "SDL_events_c.h"
+#include "SDL_timer.h"
+}; /* extern "C" */
+
+#include "SDL_epocvideo.h"
+#include "SDL_epocevents_c.h"
+
+#include<linereader.h>
+#include<bautils.h>
+
+
+#include <hal.h>
+
+extern "C" {
+/* The translation tables from a console scancode to a SDL keysym */
+static SDLKey keymap[MAX_SCANCODE];
+static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
+void DisableKeyBlocking(_THIS);
+}; /* extern "C" */
+
+TBool isCursorVisible = EFalse;
+
+int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
+{
+ int posted = 0;
+ SDL_keysym keysym;
+
+// SDL_TRACE1("hws %d", aWsEvent.Type());
+
+ switch (aWsEvent.Type())
+ {
+ case EEventPointer: /* Mouse pointer events */
+ {
+
+ const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
+
+ if(mode == EPointerCursorNone)
+ {
+ return 0; //TODO: Find out why events are get despite of cursor should be off
+ }
+
+ const TPointerEvent* pointerEvent = aWsEvent.Pointer();
+ TPoint mousePos = pointerEvent->iPosition;
+
+ /*!! TODO Pointer do not yet work properly
+ //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
+
+ if (Private->EPOC_ShrinkedHeight) {
+ mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
+ }
+ if (Private->EPOC_ShrinkedWidth) {
+ mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
+ }
+ */
+
+ posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
+
+ switch (pointerEvent->iType)
+ {
+ case TPointerEvent::EButton1Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
+ break;
+ case TPointerEvent::EButton1Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ break;
+ case TPointerEvent::EButton2Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
+ break;
+ case TPointerEvent::EButton2Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
+ break;
+ case TPointerEvent::EButton3Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
+ break;
+ case TPointerEvent::EButton3Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
+ break;
+ } // switch
+ break;
+ }
+
+ case EEventKeyDown: /* Key events */
+ {
+#ifdef SYMBIAN_CRYSTAL
+ // special case: 9300/9500 rocker down, simulate left mouse button
+ if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
+ {
+ const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
+ if(mode != EPointerCursorNone)
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
+ }
+#endif
+ (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
+
+#ifndef DISABLE_JOYSTICK
+ /* Special handling */
+ switch((int)keysym.sym) {
+ case SDLK_CAPSLOCK:
+ if (!isCursorVisible) {
+ /* Enable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
+ }
+ else {
+ /* Disable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
+ }
+ isCursorVisible = !isCursorVisible;
+ break;
+ }
+#endif
+ posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ break;
+ }
+
+ case EEventKeyUp: /* Key events */
+ {
+#ifdef SYMBIAN_CRYSTAL
+ // special case: 9300/9500 rocker up, simulate left mouse button
+ if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
+ {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ }
+#endif
+ posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
+ break;
+ }
+
+ case EEventFocusGained: /* SDL window got focus */
+ {
+ Private->EPOC_IsWindowFocused = ETrue;
+ posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+ /* Draw window background and screen buffer */
+ DisableKeyBlocking(_this); //Markus: guess why:-)
+
+ RedrawWindowL(_this);
+ break;
+ }
+
+ case EEventFocusLost: /* SDL window lost focus */
+ {
+/*
+ CFbsBitmap* bmp = new (ELeave) CFbsBitmap();
+ bmp->Create(Private->EPOC_ScreenSize, Private->EPOC_DisplayMode);
+ Private->EPOC_WsScreen->CopyScreenToBitmap(bmp);
+ Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
+ Private->EPOC_WsWindow.BeginRedraw(TRect(Private->EPOC_WsWindow.Size()));
+ Private->EPOC_WindowGc->BitBlt(TPoint(0, 0), bmp);
+ Private->EPOC_WsWindow.EndRedraw();
+ Private->EPOC_WindowGc->Deactivate();
+ bmp->Save(_L("C:\\scr.mbm"));
+ delete bmp;
+*/
+
+ Private->EPOC_IsWindowFocused = EFalse;
+
+ posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+
+ RWsSession s;
+ s.Connect();
+ RWindowGroup g(s);
+ g.Construct(TUint32(&g), EFalse);
+ g.EnableReceiptOfFocus(EFalse);
+ RWindow w(s);
+ w.Construct(g, TUint32(&w));
+ w.SetExtent(TPoint(0, 0), Private->EPOC_WsWindow.Size());
+ w.SetOrdinalPosition(0);
+ w.Activate();
+ w.Close();
+ g.Close();
+ s.Close();
+
+/*
+ Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(Private->EPOC_WsWindowGroupID, -1);
+
+
+ SDL_Delay(500);
+ TInt focus = -1;
+ while(focus < 0)
+ {
+ const TInt curr = Private->EPOC_WsSession.GetFocusWindowGroup();
+ if(curr != Private->EPOC_WsWindowGroupID)
+ focus = curr;
+ else
+ SDL_Delay(500);
+ }
+
+ if(1 < Private->EPOC_WsSession.GetWindowGroupOrdinalPriority(Private->EPOC_WsWindowGroupID))
+ {
+ Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, -1);
+ SDL_Delay(500);
+ Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, 0);
+ }
+*/
+ /*//and the request redraw
+ TRawEvent redrawEvent;
+ redrawEvent.Set(TRawEvent::ERedraw);
+ Private->EPOC_WsSession.SimulateRawEvent(redrawEvent);
+ Private->EPOC_WsSession.Flush();*/
+#if 0
+ //!! Not used
+ // Wait and eat events until focus is gained again
+ while (ETrue) {
+ Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
+ User::WaitForRequest(Private->EPOC_WsEventStatus);
+ Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
+ TInt eventType = Private->EPOC_WsEvent.Type();
+ Private->EPOC_WsEventStatus = KRequestPending;
+ //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
+ if (eventType == EEventFocusGained) {
+ RedrawWindowL(_this);
+ break;
+ }
+ }
+#endif
+ break;
+ }
+
+ case EEventModifiersChanged:
+ {
+ TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
+ TUint modstate = KMOD_NONE;
+ if (modEvent->iModifiers == EModifierLeftShift)
+ modstate |= KMOD_LSHIFT;
+ if (modEvent->iModifiers == EModifierRightShift)
+ modstate |= KMOD_RSHIFT;
+ if (modEvent->iModifiers == EModifierLeftCtrl)
+ modstate |= KMOD_LCTRL;
+ if (modEvent->iModifiers == EModifierRightCtrl)
+ modstate |= KMOD_RCTRL;
+ if (modEvent->iModifiers == EModifierLeftAlt)
+ modstate |= KMOD_LALT;
+ if (modEvent->iModifiers == EModifierRightAlt)
+ modstate |= KMOD_RALT;
+ if (modEvent->iModifiers == EModifierLeftFunc)
+ modstate |= KMOD_LMETA;
+ if (modEvent->iModifiers == EModifierRightFunc)
+ modstate |= KMOD_RMETA;
+ if (modEvent->iModifiers == EModifierCapsLock)
+ modstate |= KMOD_CAPS;
+ SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
+ break;
+ }
+ default:
+ break;
+ }
+
+ return posted;
+}
+
+extern "C" {
+
+void EPOC_PumpEvents(_THIS)
+{
+ int posted = 0; // !! Do we need this?
+ //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
+ while (Private->EPOC_WsEventStatus != KRequestPending) {
+
+ Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
+ posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
+ Private->EPOC_WsEventStatus = KRequestPending;
+ Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
+ }
+}
+
+
+_LIT(KMapFileName, "C:\\sdl_info\\sdlkeymap.cfg");
+LOCAL_C void ReadL(RFs& aFs, RArray<TInt>& aArray)
+ {
+ TInt drive = -1;
+ TFileName name(KMapFileName);
+ for(TInt i = 'z'; drive < 0 && i >= 'a'; i--)
+ {
+ name[0] = (TUint16)i;
+ if(BaflUtils::FileExists(aFs, name))
+ drive = i;
+ }
+ if(drive < 0)
+ return;
+ CLineReader* reader = CLineReader::NewLC(aFs, name);
+ while(reader->NextL())
+ {
+ TPtrC ln = reader->Current();
+ TLex line(ln);
+ TInt n = 0;
+ for(;;)
+ {
+ const TPtrC token = line.NextToken();
+ if(token.Length() == 0)
+ break;
+ if((n & 1) != 0)
+ {
+ TInt value;
+ TLex lex(token);
+ User::LeaveIfError(lex.Val(value));
+ User::LeaveIfError(aArray.Append(value));
+ }
+ n++;
+ }
+ }
+ CleanupStack::PopAndDestroy();
+ }
+
+
+void EPOC_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the key translation table */
+ for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+
+ /* Numbers */
+ for ( i = 0; i<32; ++i ){
+ keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
+ }
+ /* e.g. Alphabet keys */
+ for ( i = 0; i<32; ++i ){
+ keymap['A' + i] = (SDLKey)(SDLK_a+i);
+ }
+
+ keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
+ keymap[EStdKeyTab] = SDLK_TAB;
+ keymap[EStdKeyEnter] = SDLK_RETURN;
+ keymap[EStdKeyEscape] = SDLK_ESCAPE;
+ keymap[EStdKeySpace] = SDLK_SPACE;
+ keymap[EStdKeyPause] = SDLK_PAUSE;
+ keymap[EStdKeyHome] = SDLK_HOME;
+ keymap[EStdKeyEnd] = SDLK_END;
+ keymap[EStdKeyPageUp] = SDLK_PAGEUP;
+ keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
+ keymap[EStdKeyDelete] = SDLK_DELETE;
+ keymap[EStdKeyUpArrow] = SDLK_UP;
+ keymap[EStdKeyDownArrow] = SDLK_DOWN;
+ keymap[EStdKeyLeftArrow] = SDLK_LEFT;
+ keymap[EStdKeyRightArrow] = SDLK_RIGHT;
+ keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
+ keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
+ keymap[EStdKeyRightShift] = SDLK_RSHIFT;
+ keymap[EStdKeyLeftAlt] = SDLK_LALT;
+ keymap[EStdKeyRightAlt] = SDLK_RALT;
+ keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
+ keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
+ keymap[EStdKeyLeftFunc] = SDLK_LMETA;
+ keymap[EStdKeyRightFunc] = SDLK_RMETA;
+ keymap[EStdKeyInsert] = SDLK_INSERT;
+ keymap[EStdKeyComma] = SDLK_COMMA;
+ keymap[EStdKeyFullStop] = SDLK_PERIOD;
+ keymap[EStdKeyForwardSlash] = SDLK_SLASH;
+ keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
+ keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
+ keymap[EStdKeySingleQuote] = SDLK_QUOTE;
+ keymap[EStdKeyHash] = SDLK_HASH;
+ keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
+ keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
+ keymap[EStdKeyMinus] = SDLK_MINUS;
+ keymap[EStdKeyEquals] = SDLK_EQUALS;
+
+ keymap[EStdKeyF1] = SDLK_F1; /* chr + q */
+ keymap[EStdKeyF2] = SDLK_F2; /* chr + w */
+ keymap[EStdKeyF3] = SDLK_F3; /* chr + e */
+ keymap[EStdKeyF4] = SDLK_F4; /* chr + r */
+ keymap[EStdKeyF5] = SDLK_F5; /* chr + t */
+ keymap[EStdKeyF6] = SDLK_F6; /* chr + y */
+ keymap[EStdKeyF7] = SDLK_F7; /* chr + i */
+ keymap[EStdKeyF8] = SDLK_F8; /* chr + o */
+
+ keymap[EStdKeyF9] = SDLK_F9; /* chr + a */
+ keymap[EStdKeyF10] = SDLK_F10; /* chr + s */
+ keymap[EStdKeyF11] = SDLK_F11; /* chr + d */
+ keymap[EStdKeyF12] = SDLK_F12; /* chr + f */
+
+ #ifndef SYMBIAN_CRYSTAL
+ //!!7650 additions
+ #ifdef __WINS__
+ keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
+ #else
+ keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
+ #endif
+ keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
+ keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */
+ keymap[EStdKeyNo] = SDLK_END; /* "end call" key */
+ keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */
+ keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */
+ keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */
+ #endif
+
+ #ifdef SYMBIAN_CRYSTAL
+ keymap[EStdKeyMenu] = SDLK_ESCAPE; // menu key
+ keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left
+ keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right
+ keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up
+ keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down
+ keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr?
+ keymap[EStdKeyRightFunc] = SDLK_RALT;
+ keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */
+#endif
+
+ ///////////////////////////////////////////////////////////
+
+ RFs fs;
+ if(KErrNone == fs.Connect())
+ {
+ RArray<TInt> array;
+ TRAPD(err, ReadL(fs, array));
+ if(err == KErrNone && array.Count() > 0)
+ {
+
+ SDLKey temp[MAX_SCANCODE];
+ Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
+
+ for(TInt k = 0; k < array.Count(); k+= 2)
+ {
+ const TInt oldval = array[k];
+ const TInt newval = array[k + 1];
+ if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE)
+ {
+ keymap[oldval] = temp[newval];
+ }
+ }
+ }
+ array.Close();
+ }
+
+ fs.Close();
+ ///////////////////////////////////////////////////////////
+
+ /* !!TODO
+ EStdKeyNumLock=0x1b,
+ EStdKeyScrollLock=0x1c,
+
+ EStdKeyNkpForwardSlash=0x84,
+ EStdKeyNkpAsterisk=0x85,
+ EStdKeyNkpMinus=0x86,
+ EStdKeyNkpPlus=0x87,
+ EStdKeyNkpEnter=0x88,
+ EStdKeyNkp1=0x89,
+ EStdKeyNkp2=0x8a,
+ EStdKeyNkp3=0x8b,
+ EStdKeyNkp4=0x8c,
+ EStdKeyNkp5=0x8d,
+ EStdKeyNkp6=0x8e,
+ EStdKeyNkp7=0x8f,
+ EStdKeyNkp8=0x90,
+ EStdKeyNkp9=0x91,
+ EStdKeyNkp0=0x92,
+ EStdKeyNkpFullStop=0x93,
+ EStdKeyMenu=0x94,
+ EStdKeyBacklightOn=0x95,
+ EStdKeyBacklightOff=0x96,
+ EStdKeyBacklightToggle=0x97,
+ EStdKeyIncContrast=0x98,
+ EStdKeyDecContrast=0x99,
+ EStdKeySliderDown=0x9a,
+ EStdKeySliderUp=0x9b,
+ EStdKeyDictaphonePlay=0x9c,
+ EStdKeyDictaphoneStop=0x9d,
+ EStdKeyDictaphoneRecord=0x9e,
+ EStdKeyHelp=0x9f,
+ EStdKeyOff=0xa0,
+ EStdKeyDial=0xa1,
+ EStdKeyIncVolume=0xa2,
+ EStdKeyDecVolume=0xa3,
+ EStdKeyDevice0=0xa4,
+ EStdKeyDevice1=0xa5,
+ EStdKeyDevice2=0xa6,
+ EStdKeyDevice3=0xa7,
+ EStdKeyDevice4=0xa8,
+ EStdKeyDevice5=0xa9,
+ EStdKeyDevice6=0xaa,
+ EStdKeyDevice7=0xab,
+ EStdKeyDevice8=0xac,
+ EStdKeyDevice9=0xad,
+ EStdKeyDeviceA=0xae,
+ EStdKeyDeviceB=0xaf,
+ EStdKeyDeviceC=0xb0,
+ EStdKeyDeviceD=0xb1,
+ EStdKeyDeviceE=0xb2,
+ EStdKeyDeviceF=0xb3,
+ EStdKeyApplication0=0xb4,
+ EStdKeyApplication1=0xb5,
+ EStdKeyApplication2=0xb6,
+ EStdKeyApplication3=0xb7,
+ EStdKeyApplication4=0xb8,
+ EStdKeyApplication5=0xb9,
+ EStdKeyApplication6=0xba,
+ EStdKeyApplication7=0xbb,
+ EStdKeyApplication8=0xbc,
+ EStdKeyApplication9=0xbd,
+ EStdKeyApplicationA=0xbe,
+ EStdKeyApplicationB=0xbf,
+ EStdKeyApplicationC=0xc0,
+ EStdKeyApplicationD=0xc1,
+ EStdKeyApplicationE=0xc2,
+ EStdKeyApplicationF=0xc3,
+ EStdKeyYes=0xc4,
+ EStdKeyNo=0xc5,
+ EStdKeyIncBrightness=0xc6,
+ EStdKeyDecBrightness=0xc7,
+ EStdKeyCaseOpen=0xc8,
+ EStdKeyCaseClose=0xc9
+ */
+
+}
+
+
+
+static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
+{
+// char debug[256];
+ //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
+
+ /* Set the keysym information */
+
+ keysym->scancode = scancode;
+
+ if ((scancode >= MAX_SCANCODE) &&
+ ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
+ SDL_SetError("Too big scancode");
+ keysym->scancode = SDLK_UNKNOWN;
+ keysym->mod = KMOD_NONE;
+ return keysym;
+ }
+
+ keysym->mod = SDL_GetModState();
+
+ /* Handle function keys: F1, F2, F3 ... */
+ if (keysym->mod & KMOD_META) {
+ if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
+ switch(scancode) {
+ case 'Q': scancode = EStdKeyF1; break;
+ case 'W': scancode = EStdKeyF2; break;
+ case 'E': scancode = EStdKeyF3; break;
+ case 'R': scancode = EStdKeyF4; break;
+ case 'T': scancode = EStdKeyF5; break;
+ case 'Y': scancode = EStdKeyF6; break;
+ case 'U': scancode = EStdKeyF7; break;
+ case 'I': scancode = EStdKeyF8; break;
+ case 'A': scancode = EStdKeyF9; break;
+ case 'S': scancode = EStdKeyF10; break;
+ case 'D': scancode = EStdKeyF11; break;
+ case 'F': scancode = EStdKeyF12; break;
+ }
+ keysym->sym = keymap[scancode];
+ }
+ }
+
+ if (scancode >= ENonCharacterKeyBase) {
+ // Non character keys
+ keysym->sym = keymap[scancode -
+ ENonCharacterKeyBase + 0x0081]; // !!hard coded
+ } else {
+ keysym->sym = keymap[scancode];
+ }
+
+ /* Remap the arrow keys if the device is rotated */
+ if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
+ switch(keysym->sym) {
+ case SDLK_UP: keysym->sym = SDLK_LEFT; break;
+ case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
+ case SDLK_LEFT: keysym->sym = SDLK_DOWN; break;
+ case SDLK_RIGHT:keysym->sym = SDLK_UP; break;
+ }
+ }
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+
+#if 0 // !!TODO:unicode
+
+ if ( SDL_TranslateUNICODE )
+ {
+ /* Populate the unicode field with the ASCII value */
+ keysym->unicode = scancode;
+ }
+#endif
+
+ //!!
+ //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
+ // keysym->scancode, keysym->sym, keysym->mod);
+ //SDL_TRACE(debug); //!!
+
+ return(keysym);
+}
+
+}; /* extern "C" */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.cpp
new file mode 100644
index 0000000..06874d5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.cpp
@@ -0,0 +1,1356 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+/*
+ SDL_epocvideo.cpp
+ Epoc based SDL video driver implementation
+
+ Thanks to Peter van Sebille, the author of EMame. It is a great example of
+ low level graphics coding in Epoc.
+
+ Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
+ Assembler routines by Kimmo Kinnunen
+*/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+extern "C" {
+#include "SDL_error.h"
+#include "SDL_timer.h"
+#include "SDL_video.h"
+#undef NULL
+#include "SDL_pixels_c.h"
+#include "SDL.h"
+};
+
+#include "SDL_epocvideo.h"
+#include "SDL_epocevents_c.h"
+
+#include "sdl_epocruntime.h"
+
+#include <hal.h>
+#include <coedef.h>
+#include <flogger.h>
+
+#ifdef SYMBIAN_QUARTZ
+SDL_VideoDevice* _thisDevice;
+#endif
+
+_LIT(KLibName, "SDL");
+
+/* For debugging */
+
+//if old SOS, from 7.x this is public!
+class CLockable : public CFbsBitmap
+ {
+ public:
+ static CLockable* Lockable(CFbsBitmap* aBmp) {return static_cast<CLockable*>(aBmp);}
+ void Lock() {LockHeap();}
+ void Unlock() {UnlockHeap();}
+ };
+#define LockHeap(x) CLockable::Lockable(x)->Lock()
+#define UnlockHeap(x) CLockable::Lockable(x)->Unlock()
+
+void RDebug_Print_b(char* error_str, void* param)
+ {
+ TBuf8<128> error8((TUint8*)error_str);
+ TBuf<128> error;
+ error.Copy(error8);
+
+#ifndef TRACE_TO_FILE
+ if (param) //!! Do not work if the parameter is really 0!!
+ RDebug::Print(error, param);
+ else
+ RDebug::Print(error);
+#else
+ if (param) //!! Do not work if the parameter is really 0!!
+ RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param);
+ else
+ RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error);
+#endif
+
+ }
+
+extern "C" void RDebug_Print(char* error_str, void* param)
+ {
+ RDebug_Print_b(error_str, param);
+ }
+
+
+int Debug_AvailMem2()
+ {
+ //User::CompressAllHeaps();
+ TMemoryInfoV1Buf membuf;
+ User::LeaveIfError(UserHal::MemoryInfo(membuf));
+ TMemoryInfoV1 minfo = membuf();
+ return(minfo.iFreeRamInBytes);
+ }
+
+extern "C" int Debug_AvailMem()
+ {
+ return(Debug_AvailMem2());
+ }
+
+
+extern "C" {
+
+/* Initialization/Query functions */
+
+static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void EPOC_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+
+static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
+static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+static int EPOC_Available(void);
+static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
+
+void DrawBackground(_THIS);
+void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
+void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
+
+/* Mouse functions */
+
+static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
+static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
+
+
+
+/* !!For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit */
+// TUint16 is enough, but using TUint32 so we can use better instruction selection on ARMI
+static TUint32 EPOC_HWPalette_256_to_Screen[256];
+
+VideoBootStrap EPOC_bootstrap = {
+ "epoc", "EPOC system",
+ EPOC_Available, EPOC_CreateDevice
+};
+
+const TUint32 WindowClientHandle = 9210; //!! const
+
+/* Epoc video driver bootstrap functions */
+
+static int EPOC_Available(void)
+{
+ return 1; /* Always available */
+}
+
+static void EPOC_DeleteDevice(SDL_VideoDevice *device)
+{
+ free(device->hidden);
+ free(device);
+}
+
+static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/)
+{
+ SDL_VideoDevice *device;
+
+ SDL_TRACE("SDL:EPOC_CreateDevice");
+
+ /* Allocate all variables that we free on delete */
+ device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ free(device);
+ }
+ return(0);
+ }
+ memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = EPOC_VideoInit;
+ device->ListModes = EPOC_ListModes;
+ device->SetVideoMode = EPOC_SetVideoMode;
+ device->SetColors = EPOC_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = EPOC_VideoQuit;
+ device->AllocHWSurface = EPOC_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = EPOC_LockHWSurface;
+ device->UnlockHWSurface = EPOC_UnlockHWSurface;
+ device->FlipHWSurface = EPOC_FlipHWSurface;
+ device->FreeHWSurface = EPOC_FreeHWSurface;
+ device->SetIcon = NULL;
+ device->SetCaption = NULL;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = EPOC_FreeWMCursor;
+ device->CreateWMCursor = EPOC_CreateWMCursor;
+ device->ShowWMCursor = EPOC_ShowWMCursor;
+ device->WarpWMCursor = NULL;
+ device->InitOSKeymap = EPOC_InitOSKeymap;
+ device->PumpEvents = EPOC_PumpEvents;
+ device->free = EPOC_DeleteDevice;
+
+ return device;
+}
+
+
+int GetBpp(TDisplayMode displaymode)
+{
+ /*TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode);
+ TInt bitsPerPixel = 1;
+ for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++);
+ return bitsPerPixel;*/
+ return TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode);
+}
+
+
+void DisableKeyBlocking(_THIS)
+ {
+ // Disable key blocking
+ TRawEvent event;
+ event.Set((TRawEvent::TType)/*EDisableKeyBlock*/51); // !!EDisableKeyBlock not found in epoc32\include!
+ Private->EPOC_WsSession.SimulateRawEvent(event);
+ }
+
+void ConstructWindowL(_THIS)
+{
+ TInt error;
+
+ SDL_TRACE("SDL:ConstructWindowL");
+ error = Private->EPOC_WsSession.Connect();
+ User::LeaveIfError(error);
+ Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession);
+ User::LeaveIfError(Private->EPOC_WsScreen->Construct());
+ User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc));
+
+ Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession);
+ User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle));
+ Private->EPOC_WsWindowGroup.SetOrdinalPosition(0);
+
+ // Set window group name (the same as process name)) !!Gives always "EPOC" in WINS
+ RProcess thisProcess;
+ TParse exeName;
+ exeName.Set(thisProcess.FileName(), NULL, NULL);
+ TBuf<32> winGroupName;
+ winGroupName.Append(0);
+ winGroupName.Append(0);
+ winGroupName.Append(0);// uid
+ winGroupName.Append(0);
+ winGroupName.Append(exeName.Name()); // caption
+ winGroupName.Append(0);
+ winGroupName.Append(0); //doc name
+ Private->EPOC_WsWindowGroup.SetName(winGroupName);
+
+ Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession);
+ // Markus, it was:
+ // User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle ));
+ // but SOS 7.0s debug does not accept same window handle twice
+ User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle - 1));
+ Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite);
+ Private->EPOC_WsWindow.Activate();
+ Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels());
+ Private->EPOC_WsWindow.SetVisible(ETrue);
+
+ Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier();
+ Private->EPOC_IsWindowFocused = EFalse;
+
+ DisableKeyBlocking(_this); //disable key blocking
+}
+
+int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ // !!TODO:handle leave functions!
+
+ int i;
+
+ SDL_TRACE("SDL:EPOC_VideoInit");
+
+ /* Initialize all variables that we clean on shutdown */
+
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ Private->SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
+ Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0;
+ }
+
+ /* Modes sorted largest to smallest */
+ Private->SDL_modelist[0]->w = 800; Private->SDL_modelist[0]->h = 250;
+ Private->SDL_modelist[1]->w = 640; Private->SDL_modelist[1]->h = 480;
+ Private->SDL_modelist[2]->w = 480; Private->SDL_modelist[2]->h = 600;
+ Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 400;
+ Private->SDL_modelist[4]->w = 352; Private->SDL_modelist[4]->h = 416;
+ Private->SDL_modelist[5]->w = 416; Private->SDL_modelist[5]->h = 352;
+ Private->SDL_modelist[6]->w = 416; Private->SDL_modelist[6]->h = 312;
+ Private->SDL_modelist[7]->w = 352; Private->SDL_modelist[7]->h = 264;
+ Private->SDL_modelist[8]->w = 800; Private->SDL_modelist[8]->h = 240; //for doom all these..
+ Private->SDL_modelist[9]->w = 640; Private->SDL_modelist[9]->h = 240;
+ Private->SDL_modelist[10]->w = 480; Private->SDL_modelist[10]->h = 240;
+ Private->SDL_modelist[11]->w = 640; Private->SDL_modelist[11]->h = 240;
+ Private->SDL_modelist[12]->w = 352; Private->SDL_modelist[12]->h = 240;
+ Private->SDL_modelist[13]->w = 416; Private->SDL_modelist[13]->h = 240;
+ Private->SDL_modelist[14]->w = 416; Private->SDL_modelist[14]->h = 240;
+ Private->SDL_modelist[15]->w = 352; Private->SDL_modelist[15]->h = 240;
+ Private->SDL_modelist[16]->w = 640; Private->SDL_modelist[16]->h = 200;
+ Private->SDL_modelist[17]->w = 320; Private->SDL_modelist[17]->h = 240; //...for doom, currently engine renders no-higher windows :-(, propably should get fixed
+ Private->SDL_modelist[18]->w = 320; Private->SDL_modelist[18]->h = 200;
+ Private->SDL_modelist[19]->w = 256; Private->SDL_modelist[19]->h = 192;
+ Private->SDL_modelist[20]->w = 176; Private->SDL_modelist[20]->h = 208;
+ Private->SDL_modelist[21]->w = 208; Private->SDL_modelist[21]->h = 176; // Rotated
+ Private->SDL_modelist[22]->w = 160; Private->SDL_modelist[22]->h = 144;
+
+ Private->SDL_modelist[23]->w = 640; Private->SDL_modelist[2]->h = 200; //s80 some new modes
+ Private->SDL_modelist[24]->w = 640; Private->SDL_modelist[2]->h = 320; //s90 modes are added
+ Private->SDL_modelist[25]->w = 640; Private->SDL_modelist[2]->h = 240; //here
+ Private->SDL_modelist[26]->w = 640; Private->SDL_modelist[4]->h = 200; //now
+
+ Private->SDL_modelist[27] = NULL;
+
+ /* Construct Epoc window */
+
+ ConstructWindowL(_this);
+
+ /* Initialise Epoc frame buffer */
+
+ TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode();
+
+#if !defined(__WINS__) && !defined(TEST_BM_DRAW)
+
+ TScreenInfoV01 screenInfo;
+ TPckg<TScreenInfoV01> sInfo(screenInfo);
+ UserSvr::ScreenInfo(sInfo);
+
+ Private->EPOC_ScreenSize = screenInfo.iScreenSize;
+ Private->EPOC_DisplayMode = displayMode;
+ Private->EPOC_HasFrameBuffer = screenInfo.iScreenAddressValid;
+ Private->EPOC_FrameBuffer = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL;
+ Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
+
+ Private->EPOC_BytesPerScanLine = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel;
+ Private->EPOC_BytesPerScreen = Private->EPOC_BytesPerScanLine * Private->EPOC_ScreenSize.iHeight;
+
+ SDL_TRACE1("Screen width %d", screenInfo.iScreenSize.iWidth);
+ SDL_TRACE1("Screen height %d", screenInfo.iScreenSize.iHeight);
+ SDL_TRACE1("Screen dmode %d", displayMode);
+ SDL_TRACE1("Screen valid %d", screenInfo.iScreenAddressValid);
+
+ SDL_TRACE1("bpp %d", Private->EPOC_BytesPerPixel);
+ SDL_TRACE1("bpsl %d", Private->EPOC_BytesPerScanLine);
+ SDL_TRACE1("bps %d", Private->EPOC_BytesPerScreen);
+
+
+ /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the
+ * beginning of the frame buffer. E.g. Series 7 and Netbook.
+ * In 12 bpp machines the table has 16 entries.
+ */
+ if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8)
+ {
+ Private->EPOC_FrameBuffer += 512;
+ }
+ else
+ {
+ Private->EPOC_FrameBuffer += 32;
+ }
+ /*if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12)
+ Private->EPOC_FrameBuffer += 16 * 2;
+ if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 16)
+ Private->EPOC_FrameBuffer += 16 * 2;
+ */
+#else /* defined __WINS__ */
+
+ /* Create bitmap, device and context for screen drawing */
+ Private->EPOC_ScreenSize = Private->EPOC_WsScreen->SizeInPixels();
+
+ Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession);
+ Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode);
+
+ Private->EPOC_DisplayMode = displayMode;
+ Private->EPOC_HasFrameBuffer = ETrue;
+ Private->EPOC_FrameBuffer = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */
+ Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
+ Private->EPOC_BytesPerScanLine = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel;
+
+#endif /* __WINS__ */
+
+#ifndef SYMBIAN_CRYSTAL
+ // Get draw device for updating the screen
+ TScreenInfoV01 screenInfo2;
+
+ Epoc_Runtime::GetScreenInfo(screenInfo2);
+
+ TRAPD(status, Private->EPOC_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode));
+ User::LeaveIfError(status);
+#endif
+
+ /* The "best" video format should be returned to caller. */
+
+ vformat->BitsPerPixel = /*!!GetBpp(displayMode) */ 8;
+ vformat->BytesPerPixel = /*!!Private->EPOC_BytesPerPixel*/ 1;
+
+ /* Activate events for me */
+
+ Private->EPOC_WsEventStatus = KRequestPending;
+ Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
+
+ SDL_TRACE("SDL:WsEventStatus");
+ User::WaitForRequest(Private->EPOC_WsEventStatus); //Markus: I added this and ...
+
+ Private->EPOC_RedrawEventStatus = KRequestPending;
+ Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus);
+
+ SDL_TRACE("SDL:RedrawEventStatus");
+ User::WaitForRequest(Private->EPOC_RedrawEventStatus); //...this, if not catches a stray event is risen
+ //if there are active objects used, or confucing
+ //actions with User::WaitForAnyRequest
+ Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0);
+
+ Private->EPOC_ScreenOffset = TPoint(0, 0);
+
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap
+#endif
+
+ SDL_TRACE("SDL:DrawBackground");
+ DrawBackground(_this); // Clear screen
+
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ UnlockHeap(Private->EPOC_Bitmap); // Unlock bitmap heap
+#endif
+ //!! TODO: error handling
+ //if (ret != KErrNone)
+ // return(-1);
+ //else
+ return(0);
+}
+
+
+SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 /*flags*/)
+{
+ if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8)
+ return Private->SDL_modelist;
+ return NULL;
+}
+
+int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ if ((firstcolor+ncolors) > 256)
+ return -1;
+// SDL_TRACE1("colors %d", (TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode)));
+ if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 4096)
+ {
+ // Set 12 bit palette
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 4k value: 0000 rrrr gggg bbbb
+ TUint32 color4K = (colors[i].r & 0x0000f0) << 4;
+ color4K |= (colors[i].g & 0x0000f0);
+ color4K |= (colors[i].b & 0x0000f0) >> 4;
+ EPOC_HWPalette_256_to_Screen[i] = color4K;
+ }
+ }
+ else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 65536)
+ {
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 64k-colour displays effectively support RGB values
+ // with 5 bits allocated to red, 6 to green and 5 to blue
+ // 64k value: rrrr rggg gggb bbbb
+ TUint32 color64K = (colors[i].r & 0x0000f8) << 8;
+ color64K |= (colors[i].g & 0x0000fc) << 3;
+ color64K |= (colors[i].b & 0x0000f8) >> 3;
+ EPOC_HWPalette_256_to_Screen[i] = color64K;
+ }
+ }
+ else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 16777216)
+ {
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 16M-colour
+ //0000 0000 rrrr rrrr gggg gggg bbbb bbbb
+ TUint32 color16M = colors[i].r << 16;
+ color16M |= colors[i].g << 8;
+ color16M |= colors[i].b;
+ EPOC_HWPalette_256_to_Screen[i] = color16M;
+ }
+ }
+ else
+ {
+ return -2;
+ }
+ return(0);
+}
+
+
+SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 /*flags*/)
+{
+ SDL_TRACE("SDL:EPOC_SetVideoMode");
+ /* Check parameters */
+#ifdef SYMBIAN_CRYSTAL
+ if (! (bpp == 8 || bpp == 12 || bpp == 16) &&
+ (
+ (width == 640 && height == 200) ||
+ (width == 640 && height == 400) ||
+ (width == 640 && height == 480) ||
+ (width == 320 && height == 200) ||
+ (width == 320 && height == 240)
+ )) {
+ SDL_SetError("Requested video mode is not supported");
+ return NULL;
+ }
+#else // SYMBIAN_SERIES60
+ if (! (bpp == 8 || bpp == 12 || bpp == 16) &&
+ (
+ (width == 320 && height == 200) ||
+ (width == 320 && height == 240) ||
+ (width == 256 && height == 192) ||
+ (width == 176 && height == 208) ||
+ (width == 208 && height == 176) || // Rotated
+ (width == 160 && height == 144)
+ )) {
+ SDL_SetError("Requested video mode is not supported");
+ return NULL;
+ }
+#endif
+
+ if (current && current->pixels) {
+ free(current->pixels);
+ current->pixels = NULL;
+ }
+ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
+ return(NULL);
+ }
+
+ /* Set up the new mode framebuffer */
+ if (bpp == 8)
+ current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE);
+ else // 12 bpp, 16 bpp
+ current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC);
+ current->w = width;
+ current->h = height;
+ int numBytesPerPixel = ((bpp-1)>>3) + 1;
+ current->pitch = numBytesPerPixel * width; // Number of bytes in scanline
+ current->pixels = malloc(width * height * numBytesPerPixel);
+ memset(current->pixels, 0, width * height * numBytesPerPixel);
+
+ /* Set the blit function */
+ _this->UpdateRects = EPOC_DirectUpdate;
+
+ /*
+ * Logic for getting suitable screen dimensions, offset, scaling and orientation
+ */
+
+ int w = current->w;
+ int h = current->h;
+
+ // Rotate, if the screen does not fit horizontally and it is landscape screen
+/*
+ if ((width>Private->EPOC_ScreenSize.iWidth) && (width>height)) {
+ Private->EPOC_ScreenOrientation = CFbsBitGc::EGraphicsOrientationRotated270;
+ w = current->h;
+ h = current->w;
+ }
+*/
+ // Get nearest stepwise scale values for width and height. The smallest supported scaled screen is 1/2.
+ TInt scaleValue = 0;
+ Private->EPOC_ScreenXScaleValue = 1;
+ Private->EPOC_ScreenYScaleValue = 1;
+ if (w > Private->EPOC_ScreenSize.iWidth) {
+ // Find the biggest scale value that result the width that fits in the screen HW
+ for (scaleValue = 2; scaleValue++;) {
+ TInt scaledWidth = (w * (scaleValue-1))/scaleValue;
+ if (scaledWidth > Private->EPOC_ScreenSize.iWidth)
+ break;
+ }
+ Private->EPOC_ScreenXScaleValue = Max(2, scaleValue - 1);
+ w = (w * (Private->EPOC_ScreenXScaleValue-1))/Private->EPOC_ScreenXScaleValue;
+ }
+ if (h > Private->EPOC_ScreenSize.iHeight) {
+ // Find the biggest scale value that result the height that fits in the screen HW
+ for (scaleValue = 2; scaleValue++;) {
+ TInt scaledHeight = (h * (scaleValue-1))/scaleValue;
+ if (scaledHeight > Private->EPOC_ScreenSize.iHeight)
+ break;
+ }
+ Private->EPOC_ScreenYScaleValue = Max(2, scaleValue - 1);
+ h = (h * (Private->EPOC_ScreenYScaleValue-1))/Private->EPOC_ScreenYScaleValue;
+ }
+
+ /* Centralize game window on device screen */
+ Private->EPOC_ScreenOffset.iX = (Private->EPOC_ScreenSize.iWidth - w) / 2;
+ if (Private->EPOC_ScreenOffset.iX < 0)
+ Private->EPOC_ScreenOffset.iX = 0;
+ Private->EPOC_ScreenOffset.iY = (Private->EPOC_ScreenSize.iHeight - h) / 2;
+ if (Private->EPOC_ScreenOffset.iY < 0)
+ Private->EPOC_ScreenOffset.iY = 0;
+
+
+ SDL_TRACE1("View width %d", w);
+ SDL_TRACE1("View height %d", h);
+ SDL_TRACE1("View bmode %d", bpp);
+ SDL_TRACE1("View s %d", scaleValue);
+ SDL_TRACE1("View x %d", Private->EPOC_ScreenOffset.iX);
+ SDL_TRACE1("View y %d", Private->EPOC_ScreenOffset.iY);
+
+ /* We're done */
+ return(current);
+}
+
+
+void RedrawWindowL(_THIS)
+{
+
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap
+ Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
+#endif
+
+ int w = _this->screen->w;
+ int h = _this->screen->h;
+ if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
+ w = _this->screen->h;
+ h = _this->screen->w;
+ }
+ if ((w < Private->EPOC_ScreenSize.iWidth)
+ || (h < Private->EPOC_ScreenSize.iHeight)) {
+ DrawBackground(_this);
+ }
+
+ /* Tell the system that something has been drawn */
+ TRect rect = TRect(Private->EPOC_WsWindow.Size());
+ Private->EPOC_WsWindow.Invalidate(rect);
+
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ Private->EPOC_WsWindow.BeginRedraw(rect);
+ Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
+ Private->EPOC_WsWindow.EndRedraw();
+ Private->EPOC_WindowGc->Deactivate();
+ UnlockHeap(Private->EPOC_Bitmap);; // Unlock bitmap heap
+ Private->EPOC_WsSession.Flush();
+#endif
+
+ /* Draw current buffer */
+ SDL_Rect fullScreen;
+ fullScreen.x = 0;
+ fullScreen.y = 0;
+ fullScreen.w = _this->screen->w;
+ fullScreen.h = _this->screen->h;
+ EPOC_DirectUpdate(_this, 1, &fullScreen);
+}
+
+
+void DrawBackground(_THIS)
+{
+ /* Draw background */
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ //warning heap is not locked! - a function calling must ensure that it's ok
+ TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
+#else
+ TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
+#endif
+ // Draw black background
+ Mem::FillZ(screenBuffer, Private->EPOC_BytesPerScreen);
+
+#if 0
+ for (int y = 0; y < Private->EPOC_ScreenSize.iHeight; y++) {
+ for (int x = 0; x < Private->EPOC_ScreenSize.iWidth; x++) {
+#ifdef SYMBIAN_CRYSTAL
+ const TUint16 color = 0; // ((x+y)>>1) & 0xf; /* Draw blue stripes pattern, because in e.g. 320x200 mode there is a big background area*/
+#else // SYMBIAN_SERIES60
+ const TUint16 color = 0; /* Draw black background */
+#endif
+ *screenBuffer++ = color;
+ }
+ }
+#endif
+}
+
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int EPOC_AllocHWSurface(_THIS, SDL_Surface* /*surface*/)
+{
+ return(-1);
+}
+static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
+{
+ return;
+}
+
+static int EPOC_LockHWSurface(_THIS, SDL_Surface* /*surface*/)
+{
+ return(0);
+}
+static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
+{
+ return;
+}
+
+static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
+{
+ return(0);
+}
+
+static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ //TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup();//these are async services
+ // if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) { //for that cannot be called from
+ //SDL threads ???
+ if (!Private->EPOC_IsWindowFocused)
+ {
+ /* Force focus window to redraw again for cleaning away SDL screen graphics */
+/*
+ TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition();
+ Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt);
+ TRect rect = TRect(Private->EPOC_WsWindow.Size());
+ Private->EPOC_WsWindow.Invalidate(rect);
+ Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal);
+ */ /* If this is not the topmost window, wait here! Sleep for 1 second to give cpu time to
+ multitasking and poll for being the topmost window.
+ */
+ // if (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID) {
+
+ /* !!TODO: Could call GetRedraw() etc. for WsSession and redraw the screen if needed. That might be
+ needed if a small dialog comes in front of Game screen.
+ */
+ // while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID)
+
+ SDL_PauseAudio(1);
+ SDL_Delay(1000);
+ return;
+ // }
+
+ // RedrawWindowL(_this);
+ }
+
+ SDL_PauseAudio(0);
+
+ // if we are not focused, do not draw
+// if (!Private->EPOC_IsWindowFocused)
+// return;
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+ TBitmapUtil lock(Private->EPOC_Bitmap);
+ lock.Begin(TPoint(0,0)); // Lock bitmap heap
+ Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
+ TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
+#else
+ TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
+#endif
+
+ if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270)
+ DirectDrawRotated(_this, numrects, rects, screenBuffer);
+ else
+ DirectDraw(_this, numrects, rects, screenBuffer);
+
+
+#if defined(__WINS__) || defined(TEST_BM_DRAW)
+
+ TRect rect = TRect(Private->EPOC_WsWindow.Size());
+ Private->EPOC_WsWindow.Invalidate(rect);
+ Private->EPOC_WsWindow.BeginRedraw(rect);
+ Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
+ Private->EPOC_WsWindow.EndRedraw();
+ Private->EPOC_WindowGc->Deactivate();
+ lock.End(); // Unlock bitmap heap
+ Private->EPOC_WsSession.Flush();
+#else
+#ifndef SYMBIAN_CRYSTAL
+ // This is not needed in Crystal. What is the performance penalty in SERIES60?
+ TRect rect2 = TRect(Private->EPOC_WsWindow.Size());
+
+ Private->EPOC_DrawDevice->UpdateRegion(rect2); // Should we update rects parameter area only??
+ Private->EPOC_DrawDevice->Update();
+#endif
+#endif
+
+ /* Update virtual cursor. !!Do not yet work properly
+ Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition());
+ */
+
+ /*static int foo = 1;
+
+ for ( int i=0; i < numrects; ++i ) {
+ const SDL_Rect& currentRect = rects[i];
+ SDL_Rect rect2;
+ rect2.x = currentRect.x;
+ rect2.y = currentRect.y;
+ rect2.w = currentRect.w;
+ rect2.h = currentRect.h;
+
+ if (rect2.w <= 0 || rect2.h <= 0)
+ continue;
+
+
+ foo++;
+ if((foo % 200) == 0)
+ {
+ SDL_TRACE1("foo %d", foo);
+ CFbsBitmap* b = new (ELeave) CFbsBitmap;
+ SDL_TRACE1("bee %d", (int)b);
+ int e = b->Create(TSize(currentRect.w, currentRect.h), Private->EPOC_DisplayMode);
+
+ SDL_TRACE1("err %d", e);
+ if(e != KErrNone)
+ User::Panic(_L("damn"), e);
+
+ TBitmapUtil u(b);
+ u.Begin(TPoint(0, 0));
+ TUint32* d = b->DataAddress();
+
+ SDL_TRACE1("addr %d", (int)d);
+
+ for(TInt o = 0; o < currentRect.h; o++)
+ for(TInt p = 0; p < currentRect.w; p++)
+ {
+ u.SetPos(TPoint(p, o));
+ u.SetPixel(0xFFFF);
+ }
+
+ SDL_TRACE1("w %d", (int)currentRect.w);
+ SDL_TRACE1("h %d", (int)currentRect.h);
+
+ SDL_TRACE1("addr %d", (int)Private->EPOC_DisplayMode);
+
+
+ const TUint f = (TUint)Private->EPOC_FrameBuffer;
+ const TUint y = (TUint)Private->EPOC_BytesPerScreen;
+
+
+ SDL_TRACE1("frame %u", f);
+ SDL_TRACE1("bytes %u", y);
+
+ Mem::Copy(d, Private->EPOC_FrameBuffer, Private->EPOC_BytesPerScreen);
+
+ SDL_TRACE("kopied");
+
+ u.End();
+ TBuf<32> name;
+ name.Format(_L("C:\\nokia\\images\\doom%d.mbm"), (foo / 200));
+ e= b->Save(name);
+ if(e != KErrNone)
+ User::Panic(_L("damned"), e);
+ delete b;
+ }}*/
+}
+
+
+void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
+{
+ TInt i;
+
+ const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;
+ const TPoint fixedOffset = Private->EPOC_ScreenOffset;
+ const TInt screenW = _this->screen->w;
+ const TInt screenH = _this->screen->h;
+ const TInt sourceScanlineLength = screenW;
+ const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
+
+ /* Render the rectangles in the list */
+
+ for ( i=0; i < numrects; ++i ) {
+ const SDL_Rect& currentRect = rects[i];
+ SDL_Rect rect2;
+ rect2.x = currentRect.x;
+ rect2.y = currentRect.y;
+ rect2.w = currentRect.w;
+ rect2.h = currentRect.h;
+
+ if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
+ continue;
+
+ /* All variables are measured in pixels */
+
+ /* Check rects validity, i.e. upper and lower bounds */
+ TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
+ TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
+ if (maxX < 0 || maxY < 0) /* sanity check */
+ continue;
+ /* Clip from bottom */
+ maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1);
+ /* TODO: Clip from the right side */
+
+ const TInt sourceRectWidth = maxX - rect2.x + 1;
+ const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
+ const TInt sourceRectHeight = maxY - rect2.y + 1;
+ const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
+ const TUint skipValue = 1; // no skip
+
+ TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY +rect2.y) * targetScanlineLength;
+
+ // Nokia7650 native mode: 12 bpp --> 12 bpp
+ //
+
+ switch (_this->screen->format->BitsPerPixel)
+ {
+ case 12:
+ {
+ TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ if (skipValue == 1)
+ {
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ else
+ {
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case.
+ TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */
+ TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+ for(TInt x = 0 ; x < sourceRectWidth ; x++)
+ {
+ __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
+
+ *screenMemoryLinePos++ = *bitmapPos;
+ bitmapPos+=skipValue;
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ }
+ }
+ break;
+ // 256 color paletted mode: 8 bpp --> 12 bpp
+ //
+ default:
+ {
+ if(Private->EPOC_BytesPerPixel <= 2)
+ {
+ TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
+ TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+ /* Convert each pixel from 256 palette to 4k color values */
+ for(TInt x = 0 ; x < sourceRectWidth ; x++)
+ {
+ __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
+ *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++];
+ // bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ }
+ else
+ {
+ TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
+ TUint32* screenMemory = reinterpret_cast<TUint32*>(screenBuffer + targetStartOffset);
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
+ TUint32* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+ /* Convert each pixel from 256 palette to 4k color values */
+ for(TInt x = 0 ; x < sourceRectWidth ; x++)
+ {
+ __ASSERT_DEBUG(screenMemoryLinePos < (reinterpret_cast<TUint32*>(screenBuffer) + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast<TUint32*>(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
+ *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++];
+ // bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ }
+ }
+ } // switch
+ } // for
+}
+
+/*
+void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
+{
+ TInt i;
+ const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;
+ const TPoint fixedOffset = Private->EPOC_ScreenOffset;
+ const TInt screenW = _this->screen->w;
+ const TInt screenH = _this->screen->h;
+ const TInt sourceScanlineLength = screenW;
+ const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
+
+ /* Render the rectangles in the list */
+
+/* for ( i=0; i < numrects; ++i ) {
+ const SDL_Rect& currentRect = rects[i];
+ SDL_Rect rect2;
+ rect2.x = currentRect.x;
+ rect2.y = currentRect.y;
+ rect2.w = currentRect.w;
+ rect2.h = currentRect.h;
+
+ if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
+/* continue;
+
+ /* All variables are measured in pixels */
+
+ /* Check rects validity, i.e. upper and lower bounds */
+/* TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
+ TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
+ if (maxX < 0 || maxY < 0) /* sanity check */
+/* continue;
+ /* Clip from bottom */
+/* maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1);
+ /* TODO: Clip from the right side */
+
+/* TInt sourceRectWidth = maxX - rect2.x + 1;
+ const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
+ const TInt sourceRectHeight = maxY - rect2.y + 1;
+ const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
+ const TUint skipValue = Private->EPOC_ScreenXScaleValue; //1; // no skip
+
+ const TInt targetStartOffset = // = (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) ;
+ (skipValue > 1 ?
+ (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) :
+ (fixedOffset.iX + rect2.x + (fixedOffset.iY + rect2.y) * targetScanlineLength ));
+
+ __ASSERT_DEBUG(skipValue >= 1, User::Panic(KLibName, KErrArgument));
+
+ // Nokia7650 native mode: 12 bpp --> 12 bpp
+ //
+ switch (_this->screen->format->BitsPerPixel)
+ {
+ case 12:
+ {
+ TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ if (skipValue == 1)
+ {
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ else
+ {
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case.
+ TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */
+/* TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+/* for(TInt x = 0 ; x < sourceRectWidth ; x++)
+ {
+ __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
+
+ *screenMemoryLinePos++ = *bitmapPos;
+ bitmapPos+=skipValue;
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+ }
+ }
+ break;
+ // 256 color paletted mode: 8 bpp --> 12 bpp
+ //
+ default:
+ {
+ TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ if (skipValue > 1)
+ sourceRectWidth /= skipValue;
+#if defined __MARM_ARMI__
+ __asm volatile("
+ mov %4, %4, lsl #1 @ targetScanLineLength is in pixels, we need it in bytes
+ 1:
+ mov r6, %0 @ bitmapLine
+ mov r7, %2 @ screenMemory
+ mov r8, %6 @ sourceRectWidth
+ 2:
+ ldrb r4, [%0], %7 @ r4 = *bitmapPos; bitmapPos += skipValue
+ ldr r5, [%1, r4, lsl #2] @ only 16 lower bits actually used
+ subs r8, r8, #1 @ x--
+ strh r5, [%2], #2 @ *screenMemoryLinePos++ = r4
+ bne 2b
+
+ add %0, r6, %3 @ bitmapLine += sourceScanlineLength
+ add %2, r7, %4 @ screenMemory += targetScanlineLength
+ subs %5, %5, #1 @ sourceRectHeight--
+ bne 1b
+ "
+ : // no output
+ // %0 %1 %2 %3 %4 %5 %6 %7
+ : "r" (bitmapLine), "r" (&EPOC_HWPalette_256_to_Screen[0]), "r" (screenMemory), "r" (sourceScanlineLength), "r" (targetScanlineLength), "r" (sourceRectHeight), "r" (sourceRectWidth), "r" (skipValue)
+ : "r4", "r5", "r6", "r7", "r8"
+ );
+#else
+ for(TInt y = 0 ; y < sourceRectHeight ; y++)
+ {
+ TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
+/* TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+ /* Convert each pixel from 256 palette to 4k color values */
+/* for (TInt x = 0 ; x < sourceRectWidth ; x++)
+ {
+ //__ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt));
+ //__ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
+ //__ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
+ //__ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
+
+ *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos];
+ bitmapPos += skipValue;
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory += targetScanlineLength;
+ }
+//#endif
+ }
+ } // switch
+ } // for
+}
+*/
+
+void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
+{
+ TInt i;
+// TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;
+ TPoint fixedScreenOffset = Private->EPOC_ScreenOffset;
+ TInt bufferW = _this->screen->w;
+ TInt bufferH = _this->screen->h;
+ TInt ScreenW = Private->EPOC_ScreenSize.iWidth;
+// TInt ScreenH = Private->EPOC_ScreenSize.iWidth;
+ TInt sourceW = bufferW;
+ TInt sourceH = bufferH;
+ TInt targetW = ScreenW - fixedScreenOffset.iX * 2;
+// TInt targetH = ScreenH - fixedScreenOffset.iY * 2;
+ TInt sourceScanlineLength = bufferW;
+ TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
+
+ /* Render the rectangles in the list */
+
+ for ( i=0; i < numrects; ++i ) {
+ SDL_Rect rect2;
+ const SDL_Rect& currentRect = rects[i];
+ rect2.x = currentRect.x;
+ rect2.y = currentRect.y;
+ rect2.w = currentRect.w;
+ rect2.h = currentRect.h;
+
+ if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
+ continue;
+
+ /* All variables are measured in pixels */
+
+ /* Check rects validity, i.e. upper and lower bounds */
+ TInt maxX = Min(sourceW - 1, rect2.x + rect2.w - 1);
+ TInt maxY = Min(sourceH - 1, rect2.y + rect2.h - 1);
+ if (maxX < 0 || maxY < 0) /* sanity check */
+ continue;
+ /* Clip from bottom */
+ //maxX = Min(maxX, Private->EPOC_ScreenSize.iHeight-1);
+ /* TODO: Clip from the right side */
+
+ TInt sourceRectWidth = maxX - rect2.x + 1;
+// TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
+ TInt sourceRectHeight = maxY - rect2.y + 1;
+ TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
+ TInt targetStartOffset = fixedScreenOffset.iX + (targetW-1 - rect2.y) + (fixedScreenOffset.iY +rect2.x) * targetScanlineLength;
+
+ // Nokia7650 native mode: 12 bpp --> 12 bpp
+ if (_this->screen->format->BitsPerPixel == 12) {
+
+ /* !!TODO: not yet implemented
+
+ TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ for(TInt y = 0 ; y < sourceRectHeight ; y++) {
+ //TODO: optimize: separate loops for 1, 2 and n skip
+ //Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
+ TUint16* bitmapPos = bitmapLine; // 2 bytes per pixel
+ TUint16* screenMemoryLinePos = screenMemory; // 2 bytes per pixel
+ for(TInt x = 0 ; x < sourceRectWidth ; x++) {
+
+ __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
+
+ *screenMemoryLinePos = *bitmapPos;
+ bitmapPos++;
+ screenMemoryLinePos += targetScanlineLength;
+ }
+ bitmapLine += sourceScanlineLength;
+ screenMemory--;
+ }
+
+ */
+ }
+ // 256 color paletted mode: 8 bpp --> 12 bpp
+ else {
+ TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
+ TUint16* screenMemory = screenBuffer + targetStartOffset;
+ TInt screenXScaleValue = Private->EPOC_ScreenXScaleValue;
+ TInt debug_ycount=0;
+ for(TInt y = 0 ; y < sourceRectHeight ; y++) {
+ if(--screenXScaleValue) {
+ TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
+ TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
+ TInt screenYScaleValue = Private->EPOC_ScreenYScaleValue;
+ TInt debug_xcount=0;
+ /* Convert each pixel from 256 palette to 4k color values */
+ for(TInt x = 0 ; x < sourceRectWidth ; x++) {
+ if(--screenYScaleValue) {
+
+ __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
+ __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
+
+ *screenMemoryLinePos = TUint16(EPOC_HWPalette_256_to_Screen[*bitmapPos]);
+ screenMemoryLinePos += targetScanlineLength; debug_xcount++;
+ }
+ else
+ screenYScaleValue = Private->EPOC_ScreenYScaleValue;
+ bitmapPos++;
+ }
+ screenMemory--; debug_ycount++;
+ } // endif
+ else
+ screenXScaleValue = Private->EPOC_ScreenXScaleValue;
+ bitmapLine += sourceScanlineLength;
+ }
+ }
+ }
+}
+
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void EPOC_VideoQuit(_THIS)
+{
+ int i;
+
+ /* Free video mode lists */
+ for ( i=0; i<SDL_NUMMODES; ++i ) {
+ if ( Private->SDL_modelist[i] != NULL ) {
+ free(Private->SDL_modelist[i]);
+ Private->SDL_modelist[i] = NULL;
+ }
+ }
+
+ if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) {
+ /* Direct screen access, no memory buffer */
+ _this->screen->pixels = NULL;
+ }
+
+ if (_this->screen && _this->screen->pixels) {
+ free(_this->screen->pixels);
+ _this->screen->pixels = NULL;
+ }
+
+ /* Free Epoc resources */
+
+ /* Disable events for me */
+ if (Private->EPOC_WsEventStatus != KRequestPending)
+ Private->EPOC_WsSession.EventReadyCancel();
+ if (Private->EPOC_RedrawEventStatus != KRequestPending)
+ Private->EPOC_WsSession.RedrawReadyCancel();
+
+ #if defined(__WINS__) || defined(TEST_BM_DRAW)
+ delete Private->EPOC_Bitmap;
+ Private->EPOC_Bitmap = NULL;
+ #else
+ #endif
+
+#ifndef SYMBIAN_CRYSTAL
+ free(Private->EPOC_DrawDevice);
+#endif
+
+ if (Private->EPOC_WsWindow.WsHandle())
+ Private->EPOC_WsWindow.Close();
+
+ if (Private->EPOC_WsWindowGroup.WsHandle())
+ Private->EPOC_WsWindowGroup.Close();
+
+ delete Private->EPOC_WindowGc;
+ Private->EPOC_WindowGc = NULL;
+
+ delete Private->EPOC_WsScreen;
+ Private->EPOC_WsScreen = NULL;
+
+ if (Private->EPOC_WsSession.WsHandle())
+ Private->EPOC_WsSession.Close();
+}
+
+
+WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
+{
+ return (WMcursor *) 9210; // it's ok to return something unuseful but true
+}
+
+void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
+{
+ /* Disable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
+ Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
+}
+
+int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+
+ if (cursor == (WMcursor *)9210) {
+ /* Enable virtual cursor */
+ Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal);
+ if (isCursorVisible)
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
+ else
+ Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
+ }
+ else {
+ /* Disable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
+ Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
+ }
+
+ return(1);
+}
+
+}; // extern "C"
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.h b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.h
new file mode 100644
index 0000000..bd0b0e2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA1/SDL_epocvideo.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+#ifndef _SDL_epocvideo_h
+#define _SDL_epocvideo_h
+
+#ifndef EKA2
+#include"SDL_epocvideo_org.h"
+#else
+#include"SDL_epocvideo2.h"
+#endif
+
+
+#endif
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocevents.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocevents.cpp
new file mode 100644
index 0000000..2452dae
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocevents.cpp
@@ -0,0 +1,521 @@
+#include "epoc_sdl.h"
+
+#include <stdio.h>
+#undef NULL
+extern "C" {
+//#define DEBUG_TRACE_ENABLED
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_keysym.h"
+#include "SDL_keyboard.h"
+#include "SDL_events_c.h"
+#include "SDL_timer.h"
+} /* extern "C" */
+
+#include "SDL_epocvideo.h"
+#include "SDL_epocevents_c.h"
+
+#include "sdlepocapi.h"
+
+#include <eikenv.h>
+
+#include<bautils.h>
+
+
+extern "C"
+ {
+ static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
+ }
+
+//extern "C" {
+/* The translation tables from a console scancode to a SDL keysym */
+static SDLKey keymap[MAX_SCANCODE];
+static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
+void DisableKeyBlocking(_THIS);
+//} /* extern "C" */
+
+SDLKey* KeyMap()
+ {
+ return keymap;
+ }
+
+TBool isCursorVisible = EFalse;
+
+void ResetKeyMap()
+ {
+ int i;
+
+ /* Initialize the key translation table */
+ for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+
+ /* Numbers */
+ for ( i = 0; i<32; ++i ){
+ keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
+ }
+ /* e.g. Alphabet keys */
+ for ( i = 0; i<32; ++i ){
+ keymap['A' + i] = (SDLKey)(SDLK_a+i);
+ }
+
+ keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
+ keymap[EStdKeyTab] = SDLK_TAB;
+ keymap[EStdKeyEnter] = SDLK_RETURN;
+ keymap[EStdKeyEscape] = SDLK_ESCAPE;
+ keymap[EStdKeySpace] = SDLK_SPACE;
+ keymap[EStdKeyPause] = SDLK_PAUSE;
+ keymap[EStdKeyHome] = SDLK_HOME;
+ keymap[EStdKeyEnd] = SDLK_END;
+ keymap[EStdKeyPageUp] = SDLK_PAGEUP;
+ keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
+ keymap[EStdKeyDelete] = SDLK_DELETE;
+ keymap[EStdKeyUpArrow] = SDLK_UP;
+ keymap[EStdKeyDownArrow] = SDLK_DOWN;
+ keymap[EStdKeyLeftArrow] = SDLK_LEFT;
+ keymap[EStdKeyRightArrow] = SDLK_RIGHT;
+ keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
+ keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
+ keymap[EStdKeyRightShift] = SDLK_RSHIFT;
+ keymap[EStdKeyLeftAlt] = SDLK_LALT;
+ keymap[EStdKeyRightAlt] = SDLK_RALT;
+ keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
+ keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
+ keymap[EStdKeyLeftFunc] = SDLK_LMETA;
+ keymap[EStdKeyRightFunc] = SDLK_RMETA;
+ keymap[EStdKeyInsert] = SDLK_INSERT;
+ keymap[EStdKeyComma] = SDLK_COMMA;
+ keymap[EStdKeyFullStop] = SDLK_PERIOD;
+ keymap[EStdKeyForwardSlash] = SDLK_SLASH;
+ keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
+ keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
+ keymap[EStdKeySingleQuote] = SDLK_QUOTE;
+ keymap[EStdKeyHash] = SDLK_HASH;
+ keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
+ keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
+ keymap[EStdKeyMinus] = SDLK_MINUS;
+ keymap[EStdKeyEquals] = SDLK_EQUALS;
+
+ keymap[EStdKeyF1] = SDLK_F1;
+ keymap[EStdKeyF2] = SDLK_F2;
+ keymap[EStdKeyF3] = SDLK_F3;
+ keymap[EStdKeyF4] = SDLK_F4;
+ keymap[EStdKeyF5] = SDLK_F5;
+ keymap[EStdKeyF6] = SDLK_F6;
+ keymap[EStdKeyF7] = SDLK_F7;
+ keymap[EStdKeyF8] = SDLK_F8;
+
+ keymap[EStdKeyF9] = SDLK_F9;
+ keymap[EStdKeyF10] = SDLK_F10;
+ keymap[EStdKeyF11] = SDLK_F11;
+ keymap[EStdKeyF12] = SDLK_F12;
+
+
+ keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
+
+ keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
+ keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
+ keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */
+ keymap[EStdKeyNo] = SDLK_END; /* "end call" key */
+ keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */
+ keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */
+ keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */
+
+ keymap[EStdKeyMenu] = SDLK_MENU; // menu key
+ keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left
+ keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right
+ keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up
+ keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down
+ keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr?
+ keymap[EStdKeyRightFunc] = SDLK_RALT;
+ keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */
+
+
+
+
+
+ ///////////////////////////////////////////////////////////
+ /*
+ RFs fs;
+ if(KErrNone == fs.Connect())
+ {
+ RArray<TInt> array;
+ TRAPD(err, ReadL(fs, array));
+ if(err == KErrNone && array.Count() > 0)
+ {
+
+ SDLKey temp[MAX_SCANCODE];
+ Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
+
+ for(TInt k = 0; k < array.Count(); k+= 2)
+ {
+ const TInt oldval = array[k];
+ const TInt newval = array[k + 1];
+ if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE)
+ {
+ keymap[oldval] = temp[newval];
+ }
+ }
+ }
+ array.Close();
+ }
+
+ fs.Close();*/
+ ///////////////////////////////////////////////////////////
+
+
+ keymap[EStdKeyNumLock] = SDLK_NUMLOCK;
+ keymap[EStdKeyScrollLock] = SDLK_SCROLLOCK;
+
+ keymap[EStdKeyNkpForwardSlash] = SDLK_KP_DIVIDE;
+ keymap[EStdKeyNkpAsterisk] = SDLK_KP_MULTIPLY;
+ keymap[EStdKeyNkpMinus] = SDLK_KP_MINUS;
+ keymap[EStdKeyNkpPlus] = SDLK_KP_PLUS;
+ keymap[EStdKeyNkpEnter] = SDLK_KP_ENTER;
+ keymap[EStdKeyNkp1] = SDLK_KP1;
+ keymap[EStdKeyNkp2] = SDLK_KP2;
+ keymap[EStdKeyNkp3] = SDLK_KP3;
+ keymap[EStdKeyNkp4] = SDLK_KP4;
+ keymap[EStdKeyNkp5] = SDLK_KP5;
+ keymap[EStdKeyNkp6] = SDLK_KP6;
+ keymap[EStdKeyNkp7] = SDLK_KP7;
+ keymap[EStdKeyNkp8] = SDLK_KP8;
+ keymap[EStdKeyNkp9] = SDLK_KP9;
+ keymap[EStdKeyNkp0] = SDLK_KP0;
+ keymap[EStdKeyNkpFullStop] = SDLK_KP_PERIOD;
+ /*
+ keymap[EStdKeyMenu] = SDLK_MENU; should be, but not yet
+ keymap[EStdKeyBacklightOn] =
+ keymap[EStdKeyBacklightOff] =
+ keymap[EStdKeyBacklightToggle] =
+ keymap[EStdKeyIncContrast] =
+ keymap[EStdKeyDecContrast] =
+ keymap[EStdKeySliderDown] =
+ keymap[EStdKeySliderUp] =
+ keymap[EStdKeyDictaphonePlay] =
+ keymap[EStdKeyDictaphoneStop] =
+ keymap[EStdKeyDictaphoneRecord] =
+ keymap[EStdKeyHelp] =
+ keymap[EStdKeyOff] =
+ keymap[EStdKeyDial] =
+ keymap[EStdKeyIncVolume] =
+ keymap[EStdKeyDecVolume] =
+ keymap[EStdKeyDevice0] =
+ keymap[EStdKeyDevice1] =
+ keymap[EStdKeyDevice2] =
+ keymap[EStdKeyDevice3] =
+ keymap[EStdKeyDevice4] =
+ keymap[EStdKeyDevice5] =
+ keymap[EStdKeyDevice6] =
+ keymap[EStdKeyDevice7] =
+ keymap[EStdKeyDevice8] =
+ keymap[EStdKeyDevice9] =
+ keymap[EStdKeyDeviceA] =
+ keymap[EStdKeyDeviceB] =
+ keymap[EStdKeyDeviceC] =
+ keymap[EStdKeyDeviceD] =
+ keymap[EStdKeyDeviceE] =
+ keymap[EStdKeyDeviceF] =
+ keymap[EStdKeyApplication0] =
+ keymap[EStdKeyApplication1] =
+ keymap[EStdKeyApplication2] =
+ keymap[EStdKeyApplication3] =
+ keymap[EStdKeyApplication4] =
+ keymap[EStdKeyApplication5] =
+ keymap[EStdKeyApplication6] =
+ keymap[EStdKeyApplication7] =
+ keymap[EStdKeyApplication8] =
+ keymap[EStdKeyApplication9] =
+ keymap[EStdKeyApplicationA] =
+ keymap[EStdKeyApplicationB] =
+ keymap[EStdKeyApplicationC] =
+ keymap[EStdKeyApplicationD] =
+ keymap[EStdKeyApplicationE] =
+ keymap[EStdKeyApplicationF] =
+ keymap[EStdKeyYes] =
+ keymap[EStdKeyNo] =
+ keymap[EStdKeyIncBrightness] =
+ keymap[EStdKeyDecBrightness] =
+ keymap[EStdKeyCaseOpen] =
+ keymap[EStdKeyCaseClose] = */
+
+
+
+}
+
+
+int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
+{
+ int posted = 0;
+ SDL_keysym keysym;
+
+// SDL_TRACE1("hws %d", aWsEvent.Type());
+
+ switch (aWsEvent.Type())
+ {
+ case EEventPointer: /* Mouse pointer events */
+ {
+/* const TPointerCursorMode mode = EpocSdlEnv::PointerMode();
+
+
+ if(mode == EPointerCursorNone)
+ {
+ return 0; //TODO: Find out why events are get despite of cursor should be off
+ }
+*/
+ const TPointerEvent* pointerEvent = aWsEvent.Pointer();
+ const TPoint mousePos = EpocSdlEnv::WindowCoordinates(pointerEvent->iPosition);
+
+ /*!! TODO Pointer do not yet work properly
+ //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
+
+ if (Private->EPOC_ShrinkedHeight) {
+ mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
+ }
+ if (Private->EPOC_ShrinkedWidth) {
+ mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
+ }
+ */
+
+ posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
+
+ switch (pointerEvent->iType)
+ {
+ case TPointerEvent::EButton1Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
+ break;
+ case TPointerEvent::EButton1Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ break;
+ case TPointerEvent::EButton2Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
+ break;
+ case TPointerEvent::EButton2Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
+ break;
+ case TPointerEvent::EButton3Down:
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
+ break;
+ case TPointerEvent::EButton3Up:
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
+ break;
+ } // switch
+ break;
+ }
+
+ case EEventKeyDown: /* Key events */
+ {
+#ifdef SYMBIAN_CRYSTAL
+ // special case: 9300/9500 rocker down, simulate left mouse button
+ if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
+ {
+ const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
+ if(mode != EPointerCursorNone)
+ posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
+ }
+#endif
+ (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
+
+#ifndef DISABLE_JOYSTICK
+ /* Special handling */
+ switch((int)keysym.sym) {
+ case SDLK_CAPSLOCK:
+ if (!isCursorVisible) {
+ /* Enable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
+ }
+ else {
+ /* Disable virtual cursor */
+ HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
+ }
+ isCursorVisible = !isCursorVisible;
+ break;
+ }
+#endif
+ posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ break;
+ }
+
+ case EEventKeyUp: /* Key events */
+ {
+#ifdef SYMBIAN_CRYSTAL
+ // special case: 9300/9500 rocker up, simulate left mouse button
+ if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
+ {
+ posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
+ }
+#endif
+ posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
+ break;
+ }
+
+ case EEventFocusGained: /* SDL window got focus */
+ {
+ Private->iIsWindowFocused = ETrue;
+ posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+ /* Draw window background and screen buffer */
+ DisableKeyBlocking(_this); //Markus: guess why:-)
+
+ //RedrawWindowL(_this);
+ break;
+ }
+
+ case EEventFocusLost: /* SDL window lost focus */
+ {
+
+ Private->iIsWindowFocused = EFalse;
+
+ posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+
+
+ break;
+ }
+
+ case EEventModifiersChanged:
+ {
+ TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
+ TUint modstate = KMOD_NONE;
+ if (modEvent->iModifiers == EModifierLeftShift)
+ modstate |= KMOD_LSHIFT;
+ if (modEvent->iModifiers == EModifierRightShift)
+ modstate |= KMOD_RSHIFT;
+ if (modEvent->iModifiers == EModifierLeftCtrl)
+ modstate |= KMOD_LCTRL;
+ if (modEvent->iModifiers == EModifierRightCtrl)
+ modstate |= KMOD_RCTRL;
+ if (modEvent->iModifiers == EModifierLeftAlt)
+ modstate |= KMOD_LALT;
+ if (modEvent->iModifiers == EModifierRightAlt)
+ modstate |= KMOD_RALT;
+ if (modEvent->iModifiers == EModifierLeftFunc)
+ modstate |= KMOD_LMETA;
+ if (modEvent->iModifiers == EModifierRightFunc)
+ modstate |= KMOD_RMETA;
+ if (modEvent->iModifiers == EModifierCapsLock)
+ modstate |= KMOD_CAPS;
+ SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
+ break;
+ }
+ case EEventScreenDeviceChanged:
+ {
+ EpocSdlEnv::WaitDeviceChange();
+ }
+ break;
+ default:
+ break;
+ }
+
+ return posted;
+}
+
+extern "C" {
+
+void EPOC_PumpEvents(_THIS)
+ {
+ MEventQueue& events = EpocSdlEnv::EventQueue();
+ while(events.HasData())
+ {
+ events.Lock();
+
+ //there have to be a copy, so we can release
+ //lock immediately. HandleWsEvent may cause
+ //deadlock otherwise.
+
+ const TWsEvent event = events.Shift();
+ events.Unlock();
+// const TWsEvent& event = events.Top();
+ EPOC_HandleWsEvent(_this, event);
+// events.Shift();
+ }
+ }
+
+
+
+void EPOC_InitOSKeymap(_THIS)
+ {
+ ResetKeyMap();
+ EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0);
+ }
+
+static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
+{
+// char debug[256];
+ //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
+
+ /* Set the keysym information */
+
+ keysym->scancode = scancode;
+
+ if ((scancode >= MAX_SCANCODE) &&
+ ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
+ SDL_SetError("Too big scancode");
+ keysym->scancode = SDLK_UNKNOWN;
+ keysym->mod = KMOD_NONE;
+ return keysym;
+ }
+
+ keysym->mod = SDL_GetModState();
+
+ /* Handle function keys: F1, F2, F3 ... */
+ if (keysym->mod & KMOD_META) {
+ if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
+ switch(scancode) {
+ case 'Q': scancode = EStdKeyF1; break;
+ case 'W': scancode = EStdKeyF2; break;
+ case 'E': scancode = EStdKeyF3; break;
+ case 'R': scancode = EStdKeyF4; break;
+ case 'T': scancode = EStdKeyF5; break;
+ case 'Y': scancode = EStdKeyF6; break;
+ case 'U': scancode = EStdKeyF7; break;
+ case 'I': scancode = EStdKeyF8; break;
+ case 'A': scancode = EStdKeyF9; break;
+ case 'S': scancode = EStdKeyF10; break;
+ case 'D': scancode = EStdKeyF11; break;
+ case 'F': scancode = EStdKeyF12; break;
+ }
+ keysym->sym = keymap[scancode];
+ }
+ }
+
+ if (scancode >= ENonCharacterKeyBase) {
+ // Non character keys
+ keysym->sym = keymap[scancode -
+ ENonCharacterKeyBase + 0x0081]; // !!hard coded
+ } else {
+ keysym->sym = keymap[scancode];
+ }
+
+ /* Remap the arrow keys if the device is rotated */
+/*
+ if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
+ switch(keysym->sym) {
+ case SDLK_UP: keysym->sym = SDLK_LEFT; break;
+ case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
+ case SDLK_LEFT: keysym->sym = SDLK_DOWN; break;
+ case SDLK_RIGHT:keysym->sym = SDLK_UP; break;
+ }
+ }
+*/
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+
+#if 0 // !!TODO:unicode
+
+ if ( SDL_TranslateUNICODE )
+ {
+ /* Populate the unicode field with the ASCII value */
+ keysym->unicode = scancode;
+ }
+#endif
+
+ //!!
+ //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
+ // keysym->scancode, keysym->sym, keysym->mod);
+ //SDL_TRACE(debug); //!!
+
+ return(keysym);
+}
+
+} /* extern "C" */
+
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.cpp
new file mode 100644
index 0000000..c15506d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.cpp
@@ -0,0 +1,594 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+/*
+ SDL_epocvideo.cpp
+ Epoc based SDL video driver implementation
+
+ Markus Mertama
+*/
+
+
+
+#include "epoc_sdl.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+extern "C" {
+#include "SDL_error.h"
+#include "SDL_timer.h"
+#include "SDL_video.h"
+#undef NULL
+#include "SDL_pixels_c.h"
+#include "SDL.h"
+#include "SDL_mouse.h"
+}
+
+#include "SDL_epocvideo.h"
+#include "SDL_epocevents_c.h"
+
+
+
+#include <coedef.h>
+#include <flogger.h>
+
+#include <eikenv.h>
+#include <eikappui.h>
+#include <eikapp.h>
+#include "sdlepocapi.h"
+
+
+////////////////////////////////////////////////////////////////
+
+
+
+
+_LIT(KLibName, "SDL");
+
+void RDebug_Print_b(char* error_str, void* param)
+ {
+ TBuf8<128> error8((TUint8*)error_str);
+ TBuf<128> error;
+ error.Copy(error8);
+
+#ifndef TRACE_TO_FILE
+ if (param) //!! Do not work if the parameter is really 0!!
+ RDebug::Print(error, param);
+ else
+ RDebug::Print(error);
+#else
+ if (param) //!! Do not work if the parameter is really 0!!
+ RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param);
+ else
+ RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error);
+#endif
+
+ }
+
+extern "C" void RDebug_Print(char* error_str, void* param)
+ {
+ RDebug_Print_b(error_str, param);
+ }
+
+/*
+int Debug_AvailMem2()
+ {
+ //User::CompressAllHeaps();
+ TMemoryInfoV1Buf membuf;
+ User::LeaveIfError(UserHal::MemoryInfo(membuf));
+ TMemoryInfoV1 minfo = membuf();
+ return(minfo.iFreeRamInBytes);
+ }
+
+extern "C" int Debug_AvailMem()
+ {
+ return(Debug_AvailMem2());
+ }
+
+*/
+
+extern "C" {
+
+/* Initialization/Query functions */
+
+static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void EPOC_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+
+static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
+static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
+static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+static int EPOC_Available(void);
+static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
+
+void DrawBackground(_THIS);
+void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
+void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
+
+/* Mouse functions */
+
+static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
+static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
+}
+
+
+extern "C"
+ {
+ struct WMcursor
+ {
+ };
+ }
+
+/* Epoc video driver bootstrap functions */
+
+
+static int EPOC_Available(void)
+ {
+ return 1; /* Always available */
+ }
+
+static void EPOC_DeleteDevice(SDL_VideoDevice *device)
+ {
+ User::Free(device->hidden);
+ User::Free(device);
+ }
+
+static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/)
+ {
+ SDL_VideoDevice *device;
+
+ SDL_TRACE("SDL:EPOC_CreateDevice");
+
+ /* Allocate all variables that we free on delete */
+ device = static_cast<SDL_VideoDevice*>(User::Alloc(sizeof(SDL_VideoDevice)));
+ if ( device )
+ {
+ Mem::FillZ(device, (sizeof *device));
+ device->hidden = static_cast<struct SDL_PrivateVideoData*>
+ (User::Alloc((sizeof *device->hidden)));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) )
+ {
+ SDL_OutOfMemory();
+ if ( device ) {
+ User::Free(device);
+ }
+ return(0);
+ }
+ Mem::FillZ(device->hidden, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = EPOC_VideoInit;
+ device->ListModes = EPOC_ListModes;
+ device->SetVideoMode = EPOC_SetVideoMode;
+ device->SetColors = EPOC_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = EPOC_VideoQuit;
+ device->AllocHWSurface = EPOC_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = EPOC_LockHWSurface;
+ device->UnlockHWSurface = EPOC_UnlockHWSurface;
+ device->FlipHWSurface = EPOC_FlipHWSurface;
+ device->FreeHWSurface = EPOC_FreeHWSurface;
+ device->SetIcon = NULL;
+ device->SetCaption = NULL;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = EPOC_FreeWMCursor;
+ device->CreateWMCursor = EPOC_CreateWMCursor;
+ device->ShowWMCursor = EPOC_ShowWMCursor;
+ device->WarpWMCursor = NULL;
+ device->InitOSKeymap = EPOC_InitOSKeymap;
+ device->PumpEvents = EPOC_PumpEvents;
+ device->free = EPOC_DeleteDevice;
+
+ return device;
+}
+
+
+VideoBootStrap EPOC_bootstrap = {
+ "epoc\0\0\0", "EPOC system",
+ EPOC_Available, EPOC_CreateDevice
+};
+
+
+
+void DisableKeyBlocking(_THIS)
+ {
+ EpocSdlEnv::Request(EpocSdlEnv::EDisableKeyBlocking);
+ }
+
+void ConstructWindowL(_THIS)
+ {
+ SDL_TRACE("SDL:ConstructWindowL");
+ DisableKeyBlocking(_this); //disable key blocking
+ }
+
+
+int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
+ {
+ /* Construct Epoc window */
+
+ ConstructWindowL(_this);
+
+ /* Initialise Epoc frame buffer */
+
+
+ const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
+
+ /* The "best" video format should be returned to caller. */
+
+ vformat->BitsPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode);
+ vformat->BytesPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) / 8;
+
+
+ //?? Private->iWindow->PointerFilter(EPointerFilterDrag, 0);
+
+ Private->iScreenPos = TPoint(0, 0);
+
+ Private->iRect.x = Private->iScreenPos.iX;
+ Private->iRect.y = Private->iScreenPos.iY;
+
+ const TSize sz = EpocSdlEnv::WindowSize();
+
+ Private->iRect.w = sz.iWidth;
+ Private->iRect.h = sz.iHeight;
+ Private->iRectPtr = &Private->iRect;
+
+ return(0);
+ }
+
+
+SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+ {
+ if(flags & SDL_HWSURFACE)
+ {
+ if(format->BytesPerPixel != 4) //in HW only full color is supported
+ return NULL;
+ }
+ if(flags & SDL_FULLSCREEN)
+ {
+ return &Private->iRectPtr;
+ }
+ return (SDL_Rect **)(-1); //everythingisok, unless too small shoes
+ }
+
+
+int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+ {
+ if ((firstcolor+ncolors) > 256)
+ return -1;
+ TUint32 palette[256];
+ const TDisplayMode mode = EpocSdlEnv::DisplayMode();
+ if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096)
+ {
+ // Set 12 bit palette
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 4k value: 0000 rrrr gggg bbbb
+ TUint32 color4K = (colors[i].r & 0x0000f0) << 4;
+ color4K |= (colors[i].g & 0x0000f0);
+ color4K |= (colors[i].b & 0x0000f0) >> 4;
+ palette[i] = color4K;
+ }
+ }
+ else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536)
+ {
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 64k-colour displays effectively support RGB values
+ // with 5 bits allocated to red, 6 to green and 5 to blue
+ // 64k value: rrrr rggg gggb bbbb
+ TUint32 color64K = (colors[i].r & 0x0000f8) << 8;
+ color64K |= (colors[i].g & 0x0000fc) << 3;
+ color64K |= (colors[i].b & 0x0000f8) >> 3;
+ palette[i] = color64K;
+ }
+ }
+ else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216)
+ {
+ for(int i = firstcolor; i < ncolors; i++)
+ {
+ // 16M-colour
+ //0000 0000 rrrr rrrr gggg gggg bbbb bbbb
+ TUint32 color16M = colors[i].r << 16;
+ color16M |= colors[i].g << 8;
+ color16M |= colors[i].b;
+ palette[i] = color16M;
+ }
+ }
+ else
+ {
+ return -2;
+ }
+ if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone)
+ return 0;
+ return -1;
+ }
+
+
+/*
+void AllocHWSurfaceL(CFbsBitmap*& aBitmap, const TDisplayMode& aMode, const TSize& aSize)
+ {
+ aBitmap = new (ELeave) CFbsBitmap();
+ if(KErrNone != aBitmap->CreateHardwareBitmap(aSize, aMode,
+ EpocSdlEnv::EikonEnv().EikAppUi()->Application()->AppDllUid()))
+ //...if it fails - should we use wsbitmaps???
+ {//the good reason to use hw bitmaps is that they wont need lock heap
+ PANIC_IF_ERROR(aBitmap->Create(aSize, aMode));
+ }
+ }
+
+int CreateSurfaceL(_THIS, SDL_Surface* surface)
+ {
+ __ASSERT_ALWAYS(Private->iFrame == NULL, PANIC(KErrAlreadyExists));
+;
+ TInt dmode = EColorLast;
+
+ TDisplayMode displayMode;
+ EpocSdlEnv::GetDiplayMode(displayMode);
+
+ if(
+ TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)
+ == surface->format->BitsPerPixel)
+ {
+ dmode = displayMode;
+ }
+ else
+ {
+ --dmode;
+ while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
+ TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) !=
+ surface->format->BitsPerPixel)
+ --dmode;
+ }
+
+ __ASSERT_ALWAYS(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)), PANIC(KErrNotSupported));
+ TRAPD(err, AllocHWSurfaceL(Private->iFrame, TDisplayMode(dmode), TSize(surface->w, surface->h)));
+ return err == KErrNone ? 0 : -1;
+ }
+*/
+
+TDisplayMode GetDisplayMode(TInt aBitsPerPixel)
+ {
+ const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
+ TInt dmode = EColorLast;
+ if(
+ TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)
+ == aBitsPerPixel)
+ {
+ dmode = displayMode;
+ }
+ else
+ {
+ --dmode;
+ while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
+ TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) !=
+ aBitsPerPixel)
+ --dmode;
+ }
+ return TDisplayMode(dmode);
+ }
+
+SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+ {
+ const TSize screenSize = EpocSdlEnv::WindowSize(TSize(width, height));
+ if(width > screenSize.iWidth || height > screenSize.iHeight)
+ {
+ if(flags & SDL_FULLSCREEN)
+ {
+ width = screenSize.iWidth;
+ height = screenSize.iHeight;
+ }
+ else
+ return NULL;
+ }
+
+ if(current && current->pixels)
+ {
+ // free(current->pixels);
+ current->pixels = NULL;
+ }
+
+ if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0))
+ {
+ return(NULL);
+ }
+
+ current->flags = 0;
+ if(width == screenSize.iWidth && height == screenSize.iHeight)
+ current->flags |= SDL_FULLSCREEN;
+
+ const int numBytesPerPixel = ((bpp-1)>>3) + 1;
+ current->pitch = numBytesPerPixel * width; // Number of bytes in scanline
+
+ /* Set up the new mode framebuffer */
+ current->flags |= SDL_PREALLOC;
+
+ if(bpp <= 8)
+ current->flags |= SDL_HWPALETTE;
+
+ User::Free(Private->iSwSurface);
+ current->pixels = NULL;
+ Private->iSwSurface = NULL;
+
+ if(flags & SDL_HWSURFACE)
+ {
+ current->flags |= SDL_HWSURFACE;
+ // current->pixels = NULL;
+ // Private->iSwSurface = NULL;
+ }
+ else
+ {
+ current->flags |= SDL_SWSURFACE;
+ const TInt surfacesize = width * height * numBytesPerPixel;
+ Private->iSwSurfaceSize = TSize(width, height);
+ delete Private->iSwSurface;
+ Private->iSwSurface = NULL;
+ current->pixels = (TUint8*) User::AllocL(surfacesize);
+ Private->iSwSurface = (TUint8*) current->pixels;
+ const TInt err = EpocSdlEnv::AllocSwSurface
+ (TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
+ if(err != KErrNone)
+ return NULL;
+ }
+
+ current->w = width;
+ current->h = height;
+
+
+
+ /* Set the blit function */
+ _this->UpdateRects = EPOC_DirectUpdate;
+
+ /*
+ * Logic for getting suitable screen dimensions, offset, scaling and orientation
+ */
+
+
+ /* Centralize game window on device screen */
+
+
+ Private->iScreenPos.iX = Max(0, (screenSize.iWidth - width) / 2);
+ Private->iScreenPos.iY = Max(0, (screenSize.iHeight - height) / 2);
+
+ // delete (Private->iFrame);
+// Private->iFrame = NULL;
+
+ // TRAPD(err, CreateSurfaceL(_this, current));
+ // PANIC_IF_ERROR(err);
+
+ SDL_TRACE1("View width %d", width);
+ SDL_TRACE1("View height %d", height);
+ SDL_TRACE1("View bmode %d", bpp);
+ SDL_TRACE1("View x %d", Private->iScreenPos.iX);
+ SDL_TRACE1("View y %d", Private->iScreenPos.iY);
+
+ EpocSdlEnv::LockPalette(EFalse);
+ /* We're done */
+ return(current);
+}
+
+
+
+static int EPOC_AllocHWSurface(_THIS, SDL_Surface* surface)
+ {
+ return KErrNone == EpocSdlEnv::AllocHwSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel));
+ }
+
+static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
+ {
+ }
+
+static int EPOC_LockHWSurface(_THIS, SDL_Surface* surface)
+ {
+ if(EpocSdlEnv::IsDsaAvailable())
+ {
+ TUint8* address = EpocSdlEnv::LockHwSurface();
+ if(address != NULL)
+ {
+ surface->pixels = address;
+ return 1;
+ }
+ }
+ return 0;
+ }
+static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
+ {
+ EpocSdlEnv::UnlockHwSurface();
+ }
+
+static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
+ {
+ return(0);
+ }
+
+static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+ {
+ if(EpocSdlEnv::IsDsaAvailable())
+ {
+ if(Private->iSwSurface)
+ {
+ const TRect target(Private->iScreenPos, Private->iSwSurfaceSize);
+ for(TInt i = 0; i < numrects ;i++)
+ {
+ const TRect rect(TPoint(rects[i].x, rects[i].y),
+ TSize(rects[i].w, rects[i].h));
+ if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target))
+ return; //not succesful
+ }
+ EpocSdlEnv::UpdateSwSurface();
+ }
+ SDL_PauseAudio(0);
+ }
+ else
+ {
+ SDL_PauseAudio(1);
+ EpocSdlEnv::WaitDsaAvailable();
+ }
+ }
+
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void EPOC_VideoQuit(_THIS)
+ {
+// delete Private->iFrame;
+// Private->iFrame = NULL;
+ User::Free(Private->iSwSurface);
+ Private->iSwSurface = NULL;
+ EpocSdlEnv::FreeSurface();
+ }
+
+
+
+
+WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
+ {
+ return (WMcursor*) 1; //hii! prevents SDL to view a std cursor
+ }
+
+void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
+ {
+ }
+
+int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
+ {
+ return true;
+ }
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.h b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.h
new file mode 100644
index 0000000..5aa3a20
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/SDL_epocvideo.h
@@ -0,0 +1,51 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+#ifndef EPOCVIDEO_H
+#define EPOCVIDEO_H
+
+#include<w32std.h>
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *_this
+#define Private _this->hidden
+
+class CFbsBitmap;
+
+struct SDL_VideoDevice;
+void DisableKeyBlocking(SDL_VideoDevice*);
+
+struct SDL_PrivateVideoData
+ {
+ TPoint iScreenPos;
+ TBool iIsWindowFocused;
+ TSize iSwSurfaceSize;
+ TUint8* iSwSurface;
+ SDL_Rect iRect; //same info in SDL format
+ SDL_Rect* iRectPtr;
+ };
+
+#endif
+
+
+
+
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa.cpp
new file mode 100644
index 0000000..07b1ab4
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa.cpp
@@ -0,0 +1,1505 @@
+#include "dsa.h"
+#include "sdlepocapi.h"
+#include <cdsb.h>
+
+
+LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
+ {
+ return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
+ }
+
+
+
+
+template<class T>
+NONSHARABLE_CLASS(CBitmapSurface) : public T
+ {
+public:
+ CBitmapSurface(RWsSession& aSession);
+private:
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ ~CBitmapSurface();
+ TUint8* LockSurface();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void Free();
+ void Update(CFbsBitmap& aBmp);
+ TInt ExternalUpdate();
+private:
+ CFbsBitmap* iBmp;
+ CFbsBitmap* iCopyBmp;
+ };
+
+
+template<class T>
+void CBitmapSurface<T>::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ delete iCopyBmp;
+ iCopyBmp = NULL;
+ iCopyBmp = new (ELeave) CFbsBitmap();
+ T::ConstructL(aWindow, aDevice);
+ }
+
+template<class T>
+CBitmapSurface<T>::CBitmapSurface(RWsSession& aSession) : T(aSession)
+ {
+ }
+
+template<class T>
+void CBitmapSurface<T>::Free()
+ {
+ delete iBmp;
+ iBmp = NULL;
+ T::Free();
+ }
+
+template<class T>
+CBitmapSurface<T>::~CBitmapSurface()
+ {
+ __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
+ delete iCopyBmp;
+ }
+
+template<class T>
+TUint8* CBitmapSurface<T>::LockSurface()
+ {
+ iBmp->LockHeap();
+ return reinterpret_cast<TUint8*>(iBmp->DataAddress());
+ }
+
+
+template<class T>
+void CBitmapSurface<T>::UnlockHwSurface()
+ {
+ iBmp->UnlockHeap();
+ T::SetUpdating(EFalse);
+ Update(*iBmp);
+ }
+
+
+template<class T>
+void CBitmapSurface<T>::Update(CFbsBitmap& aBmp)
+ {
+ if(!T::Blitter(aBmp))
+ {
+ if(T::SwSize() == T::HwRect().Size())
+ T::Gc().BitBlt(T::HwRect().iTl, &aBmp);
+ else
+ T::Gc().DrawBitmap(T::HwRect(), &aBmp);
+ }
+ T::DrawOverlays();
+ T::CompleteUpdate();
+ }
+
+template<class T>
+void CBitmapSurface<T>::CreateSurfaceL()
+ {
+ Free();
+ iBmp = new (ELeave) CFbsBitmap();
+ User::LeaveIfError(iBmp->Create(T::SwSize(), T::DisplayMode()));
+ T::CreateSurfaceL(*iBmp);
+ }
+
+template<class T>
+void CBitmapSurface<T>::Wipe(TInt aLength) //dont call in drawing
+ {
+ iBmp->LockHeap();
+ Mem::FillZ(iBmp->DataAddress(), aLength);
+ iBmp->UnlockHeap();
+ }
+
+template<class T>
+TInt CBitmapSurface<T>::ExternalUpdate()
+ {
+ if(iCopyBmp->Handle() == 0)
+ {
+ const TInt err = iCopyBmp->Duplicate(iBmp->Handle());
+ if(err != KErrNone)
+ return err;
+ }
+ Update(*iCopyBmp);
+ return KErrNone;
+ }
+
+
+//////////////////////////////////////////////////////////////////////
+
+
+
+NONSHARABLE_CLASS(CDsaBitgdi) : public CDsa
+ {
+public:
+ CDsaBitgdi(RWsSession& aSession);
+protected:
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ CBitmapContext& Gc();
+ void CompleteUpdate();
+ ~CDsaBitgdi();
+ void CreateSurfaceL(CFbsBitmap& aBmp);
+ void Free();
+ void UnlockHWSurfaceRequestComplete();
+private:
+ void Resume();
+
+ CFbsBitGc* iGc;
+ CFbsDevice* iDevice;
+ CFbsBitmap* iBitGdiBmp;
+ CWindowGc* iWinGc;
+ RWindow* iWindow;
+ TInt iHandle;
+ };
+
+
+CDsaBitgdi::CDsaBitgdi(RWsSession& aSession) : CDsa(aSession)
+ {
+ }
+
+CDsaBitgdi::~CDsaBitgdi()
+ {
+ delete iWinGc;
+ delete iBitGdiBmp;
+ }
+
+void CDsaBitgdi::CompleteUpdate()
+ {
+ EpocSdlEnv::Request(CDsa::ERequestUpdate);
+ }
+
+
+void CDsaBitgdi::UnlockHWSurfaceRequestComplete()
+ {
+ if(iHandle == 0)
+ return;
+
+ if(iBitGdiBmp == NULL)
+ {
+ iBitGdiBmp = new CFbsBitmap();
+ if(iBitGdiBmp == NULL)
+ return;
+ iBitGdiBmp->Duplicate(iHandle);
+ }
+
+ iWindow->Invalidate();
+
+ iWindow->BeginRedraw();
+ iWinGc->Activate(*iWindow);
+ iWinGc->BitBlt(TPoint(0, 0), iBitGdiBmp);
+ iWinGc->Deactivate();
+ iWindow->EndRedraw();
+ }
+
+void CDsaBitgdi::Resume()
+ {
+ Start();
+ }
+
+CBitmapContext& CDsaBitgdi::Gc()
+ {
+ return *iGc;
+ }
+
+ void CDsaBitgdi::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+
+ delete iBitGdiBmp;
+ iBitGdiBmp = NULL;
+ delete iWinGc;
+ iWinGc = NULL;
+ iHandle = 0;
+
+ iWindow = &aWindow;
+ User::LeaveIfError(aDevice.CreateContext(iWinGc));
+ CDsa::ConstructL(aWindow, aDevice);
+ Start();
+ }
+
+void CDsaBitgdi::CreateSurfaceL(CFbsBitmap& aBmp)
+ {
+ iDevice = CFbsBitmapDevice::NewL(&aBmp);
+ User::LeaveIfError(iDevice->CreateContext(iGc));
+ iHandle = aBmp.Handle();
+ }
+
+void CDsaBitgdi::Free()
+ {
+ delete iGc;
+ iGc = NULL;
+ delete iDevice;
+ iDevice = NULL;
+ }
+
+////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+
+NONSHARABLE_CLASS(CDsaBase) : public CDsa, public MDirectScreenAccess
+ {
+protected:
+ inline CDirectScreenAccess& Dsa() const;
+ CDsaBase(RWsSession& aSession);
+ ~CDsaBase();
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ void Stop();
+ void Resume();
+ CBitmapContext& Gc();
+protected:
+ CDirectScreenAccess* iDsa;
+private:
+ void AbortNow(RDirectScreenAccess::TTerminationReasons aReason);
+ void Restart(RDirectScreenAccess::TTerminationReasons aReason);
+private:
+ void RestartL();
+ };
+
+
+inline CDirectScreenAccess& CDsaBase::Dsa() const
+ {
+ return *iDsa;
+ }
+
+
+CDsaBase::CDsaBase(RWsSession& aSession) : CDsa(aSession)
+ {
+ }
+
+CBitmapContext& CDsaBase::Gc()
+ {
+ return *Dsa().Gc();
+ }
+
+void CDsaBase::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ CDsa::ConstructL(aWindow, aDevice);
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ delete iDsa;
+ iDsa = NULL;
+ }
+
+ iDsa = CDirectScreenAccess::NewL(
+ Session(),
+ aDevice,
+ aWindow,
+ *this);
+ RestartL();
+ }
+
+void CDsaBase::Resume()
+ {
+ if(Stopped())
+ Restart(RDirectScreenAccess::ETerminateRegion);
+ }
+
+CDsaBase::~CDsaBase()
+ {
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ }
+ delete iDsa;
+ }
+
+
+void CDsaBase::RestartL()
+ {
+
+
+ iDsa->StartL();
+
+ const RRegion* r = iDsa->DrawingRegion();
+ const TRect rect = r->BoundingRect();
+ iDsa->Gc()->SetClippingRegion(r);
+
+ if(rect != ScreenRect())
+ {
+ return ;
+ }
+
+
+ SetTargetRect();
+ RecreateL();
+
+ Start();
+
+
+ }
+
+void CDsaBase::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
+ {
+ Stop();
+ }
+
+void CDsaBase::Restart(RDirectScreenAccess::TTerminationReasons aReason)
+ {
+ if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
+ {
+ TRAPD(err, RestartL());
+ PANIC_IF_ERROR(err);
+ }
+ }
+
+
+void CDsaBase::Stop()
+ {
+ CDsa::Stop();
+ iDsa->Cancel();
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+NONSHARABLE_CLASS(TDsa)
+ {
+ public:
+ inline TDsa(const CDsa& aDsa);
+ inline TBool IsFlip() const;
+ inline TBool IsTurn() const;
+ inline const TSize& SwSize() const;
+ inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const;
+ private:
+ const CDsa& iDsa;
+ };
+
+
+
+
+inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa)
+ {
+ }
+
+inline TBool TDsa::IsTurn() const
+ {
+ return iDsa.iStateFlags & CDsa::EOrientation90;
+ }
+
+inline TBool TDsa::IsFlip() const
+ {
+ return iDsa.iStateFlags & CDsa::EOrientation180;
+ }
+
+inline const TSize& TDsa::SwSize() const
+ {
+ return iDsa.SwSize();
+ }
+
+inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const
+ {
+ iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
+ }
+
+template<class T, class S>
+void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
+ const TUint8* aSource,
+ const TRect& aUpdateRect,
+ const TRect& aSourceRect)
+ {
+ const S* source = reinterpret_cast<const S*>(aSource);
+ const TInt lineWidth = aSourceRect.Width();
+
+ source += (aUpdateRect.iTl.iY * lineWidth);
+ const TInt sourceStartOffset = aUpdateRect.iTl.iX;
+ source += sourceStartOffset;
+
+ T* targetPtr = reinterpret_cast<T*>(aTarget);
+
+ const TInt scanLineWidth = iDsa.SwSize().iWidth;
+
+ targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth;
+ const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
+
+ targetPtr += targetStartOffset;
+
+
+ const TInt height = aUpdateRect.Height();
+
+ const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth;
+ const TInt copyLen = aUpdateRect.Width();
+
+
+ if(iDsa.IsFlip())
+ {
+
+ targetPtr += scanLineWidth * (height - 1);
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
+ source += lineMove;
+ targetPtr -= scanLineWidth;
+ }
+ }
+ else
+ {
+
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
+ source += lineMove;
+ targetPtr += scanLineWidth; // >> 2;
+ }
+ }
+
+ }
+
+
+
+NONSHARABLE_CLASS(CDsaA) : public CDsaBase
+ {
+ public:
+ CDsaA(RWsSession& aSession);
+ protected:
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ void CompleteUpdate();
+ void CreateSurfaceL(CFbsBitmap& aBmp);
+ void Free();
+ void UnlockHWSurfaceRequestComplete();
+ };
+
+
+CDsaA::CDsaA(RWsSession& aSession) : CDsaBase(aSession)
+ {
+ }
+
+
+void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ CDsaBase::ConstructL(aWindow, aDevice);
+ }
+
+void CDsaA::CompleteUpdate()
+ {
+ iDsa->ScreenDevice()->Update();
+ }
+
+void CDsaA::CreateSurfaceL(CFbsBitmap& /*aBmp*/)
+ {
+ }
+
+void CDsaA::Free()
+ {
+
+ }
+
+void CDsaA::UnlockHWSurfaceRequestComplete()
+ {
+ PANIC(KErrNotSupported);
+ }
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+NONSHARABLE_CLASS(MDsbObs)
+ {
+ public:
+ virtual void SurfaceReady() = 0;
+ virtual CDirectScreenBitmap& Dsb() = 0;
+ };
+
+NONSHARABLE_CLASS(CDsbSurface) : public CActive
+ {
+ public:
+ CDsbSurface(MDsbObs& aDsb);
+ TUint8* Address();
+ void Complete();
+ ~CDsbSurface();
+ private:
+ void RunL();
+ void DoCancel();
+ private:
+ MDsbObs& iDsb;
+ TUint8* iAddress;
+ };
+
+CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CDsbSurface::~CDsbSurface()
+ {
+ Cancel();
+ }
+
+void CDsbSurface::Complete()
+ {
+ if(iAddress != NULL && !IsActive())
+ {
+ iAddress = NULL;
+ SetActive();
+ iDsb.Dsb().EndUpdate(iStatus);
+ }
+ }
+
+TUint8* CDsbSurface::Address()
+ {
+ if(iAddress == NULL && !IsActive())
+ {
+ TAcceleratedBitmapInfo info;
+ if(KErrNone == iDsb.Dsb().BeginUpdate(info))
+ iAddress = info.iAddress;
+ }
+ return iAddress;
+ }
+
+void CDsbSurface::RunL()
+ {
+ iDsb.SurfaceReady();
+ }
+
+void CDsbSurface::DoCancel()
+ {
+ //empty
+ }
+
+NONSHARABLE_CLASS(CDsaB) : public CDsaBase,
+ public MDsbObs
+ {
+ public:
+ CDsaB(RWsSession& aSession, TInt aFlags);
+ private:
+ ~CDsaB();
+ TUint8* LockSurface();
+ void UnlockHWSurfaceRequestComplete();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void RecreateL();
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ CDirectScreenBitmap& Dsb();
+ void SurfaceReady();
+ TInt ExternalUpdate();
+ private:
+ CDsbSurface* iSurface1;
+ CDsbSurface* iSurface2;
+ CDirectScreenBitmap* iDsb;
+ TInt iType;
+ };
+
+CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsaBase(aSession), iType(aFlags)
+ {
+ }
+
+
+
+void CDsaB::UnlockHWSurfaceRequestComplete()
+ {
+ iSurface1->Complete();
+ if(iSurface2 != NULL)
+ iSurface2->Complete();
+ }
+
+void CDsaB::CreateSurfaceL()
+ {
+ __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported));
+ }
+
+void CDsaB::Wipe(TInt aLength) //dont call in drawing
+ {
+ TUint8* addr = LockSurface();
+ if(addr != NULL)
+ {
+ Mem::FillZ(addr, aLength);
+ UnlockHwSurface();
+ }
+ }
+
+
+void CDsaB::UnlockHwSurface()
+ {
+ EpocSdlEnv::Request(CDsa::ERequestUpdate);
+ }
+
+TUint8* CDsaB::LockSurface()
+ {
+ TUint8* addr = iSurface1->Address();
+ if(addr == NULL && iSurface2 != NULL)
+ addr = iSurface2->Address();
+ SetUpdating(addr == NULL);
+ return addr;
+ }
+
+void CDsaB::SurfaceReady()
+ {
+ SetUpdating(EFalse);
+ }
+
+CDirectScreenBitmap& CDsaB::Dsb()
+ {
+ return *iDsb;
+ }
+
+void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ if(iDsb == NULL)
+ iDsb = CDirectScreenBitmap::NewL();
+ CDsaBase::ConstructL(aWindow, aDevice);
+ if(iSurface1 == NULL)
+ iSurface1 = new (ELeave) CDsbSurface(*this);
+ if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer)
+ iSurface2 = new (ELeave) CDsbSurface(*this);
+ }
+
+CDsaB::~CDsaB()
+ {
+ delete iSurface1;
+ delete iSurface2;
+ delete iDsb;
+ }
+
+void CDsaB::RecreateL()
+ {
+ iDsb->Close();
+ iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType));
+ }
+
+TInt CDsaB::ExternalUpdate()
+ {
+ if(LockSurface())
+ {
+ UnlockHWSurfaceRequestComplete();
+ return KErrNone;
+ }
+ return KErrNotReady;
+ }
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+CDsa* CDsa::CreateL(RWsSession& aSession)
+ {
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
+ {
+ TInt flags = CDirectScreenBitmap::ENone;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
+ flags |= CDirectScreenBitmap::EDoubleBuffer;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrementalUpdate))
+ flags |= CDirectScreenBitmap::EIncrementalUpdate;
+ return new (ELeave) CDsaB(aSession, flags);
+ }
+ else if(EpocSdlEnv::Flags(CSDL::EDrawModeGdi))
+ {
+ return new (ELeave) CBitmapSurface<CDsaBitgdi>(aSession);
+ }
+ else
+ {
+ return new (ELeave) CBitmapSurface<CDsaA>(aSession);
+ }
+ }
+
+
+void CDsa::RecreateL()
+ {
+ }
+
+void CDsa::Free()
+ {
+ }
+
+TSize CDsa::WindowSize() const
+ {
+ TSize size = iSwSize;
+ if(iStateFlags & EOrientation90)
+ {
+ const TInt tmp = size.iWidth;
+ size.iWidth = size.iHeight;
+ size.iHeight = tmp;
+ }
+ return size;
+ }
+
+void CDsa::SetSuspend()
+ {
+ iStateFlags |= ESdlThreadSuspend;
+ }
+
+
+void CDsa::SetUpdating(TBool aUpdate)
+ {
+ if(aUpdate)
+ iStateFlags |= EUpdating;
+ else
+ iStateFlags &= ~EUpdating;
+ }
+
+
+TBool CDsa::Stopped() const
+ {
+ return (iStateFlags & ESdlThreadExplicitStop);
+ }
+
+void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
+ {
+ TInt flags = 0;
+ switch(aOrientation)
+ {
+ case CSDL::EOrientation90:
+ flags = EOrientation90;
+ break;
+ case CSDL::EOrientation180:
+ flags = EOrientation180;
+ break;
+ case CSDL::EOrientation270:
+ flags = EOrientation90 | EOrientation180;
+ break;
+ case CSDL::EOrientation0:
+ flags = 0;
+ break;
+ }
+ if(flags != (iStateFlags & EOrientationFlags))
+ {
+ iStateFlags |= EOrientationChanged;
+ iNewFlags = flags; //cannot be set during drawing...
+ }
+ }
+
+CDsa::~CDsa()
+ {
+ iOverlays.Close();
+ User::Free(iLut256);
+ }
+
+void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& /*aDevice*/)
+ {
+ if(iLut256 == NULL)
+ iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
+ iTargetMode = aWindow.DisplayMode();
+ iTargetBpp = BytesPerPixel(DisplayMode());
+ iScreenRect = TRect(aWindow.Position(), aWindow.Size());
+ SetTargetRect();
+ }
+
+void CDsa::DrawOverlays()
+ {
+ const TInt last = iOverlays.Count() - 1;
+ for(TInt i = last; i >= 0 ; i--)
+ iOverlays[i].iOverlay->Draw(Gc(), HwRect(), SwSize());
+ }
+
+TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
+ {
+ TInt i;
+ for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
+ {}
+ const TOverlay overlay = {&aOverlay, aPriority};
+ return iOverlays.Insert(overlay, i);
+ }
+
+TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
+ {
+ for(TInt i = 0; i < iOverlays.Count(); i++)
+ {
+ if(iOverlays[i].iOverlay == &aOverlay)
+ {
+ iOverlays.Remove(i);
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+void CDsa::LockPalette(TBool aLock)
+ {
+ if(aLock)
+ iStateFlags |= EPaletteLocked;
+ else
+ iStateFlags &= ~EPaletteLocked;
+ }
+TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
+ {
+ if(iLut256 == NULL)
+ return KErrNotFound;
+ const TInt count = aCount - aFirst;
+ if(count > 256)
+ return KErrArgument;
+ if(iStateFlags & EPaletteLocked)
+ return KErrNone;
+ for(TInt i = aFirst; i < count; i++) //not so busy here:-)
+ {
+ iLut256[i] = aPalette[i];
+ }
+ return KErrNone;
+ }
+
+
+
+
+
+CDsa::CDsa(RWsSession& aSession) :
+ iStateFlags(0),
+ iSession(aSession)
+
+ {
+// CActiveScheduler::Add(this);
+ iCFTable[0] = CopyMem;
+ iCFTable[1] = CopyMemFlipReversed;
+ iCFTable[2] = CopyMemReversed;
+ iCFTable[3] = CopyMemFlip;
+
+ iCFTable[4] = Copy256;
+ iCFTable[5] = Copy256FlipReversed;
+ iCFTable[6] = Copy256Reversed;
+ iCFTable[7] = Copy256Flip;
+
+
+ iCFTable[8] = CopySlow;
+ iCFTable[9] = CopySlowFlipReversed;
+ iCFTable[10] = CopySlowReversed;
+ iCFTable[11] = CopySlowFlip;
+ }
+
+RWsSession& CDsa::Session()
+ {
+ return iSession;
+ }
+
+TInt CDsa::RedrawRequest()
+ {
+ if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
+ {
+ return ExternalUpdate();
+ }
+ return KErrNotReady;
+ }
+
+TUint8* CDsa::LockHwSurface()
+ {
+ if((iStateFlags & EUpdating) == 0) //else frame is skipped
+ {
+ return LockSurface();
+ }
+ return NULL;
+ }
+
+/*
+void CDsa::RunL()
+ {
+ iStateFlags &= ~EUpdating;
+ }
+
+
+void CDsa::DoCancel()
+ {
+ iStateFlags &= ~EUpdating;
+ //nothing can do, just wait?
+ }
+*/
+
+
+TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
+ {
+ if(aHwSurface && aMode != DisplayMode())
+ return KErrArgument;
+
+ iSourceMode = aMode;
+
+ iSourceBpp = BytesPerPixel(aMode);
+
+ const TSize size = WindowSize();
+ if(aSize.iWidth > size.iWidth)
+ return KErrTooBig;
+ if(aSize.iHeight > size.iHeight)
+ return KErrTooBig;
+
+ TRAPD(err, CreateSurfaceL());
+ if(err != KErrNone)
+ return err;
+
+ SetCopyFunction();
+
+ return KErrNone;
+ }
+
+
+void CDsa::CreateZoomerL(const TSize& aSize)
+ {
+ iSwSize = aSize;
+ iStateFlags |= EResizeRequest;
+ CreateSurfaceL();
+ SetTargetRect();
+ }
+
+
+/*
+void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, aMode);
+ s->LockHeap();
+ TUint32* addr = s->DataAddress();
+ Mem::Copy(addr, aData, aLength);
+ s->UnlockHeap();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, EColor64K);
+ TBitmapUtil bmp(s);
+ bmp.Begin(TPoint(0, 0));
+ for(TInt j = 0; j < aSz.iHeight; j++)
+ {
+ bmp.SetPos(TPoint(0, j));
+ for(TInt i = 0; i < aSz.iWidth; i++)
+ {
+ bmp.SetPixel(*aData);
+ aData++;
+ bmp.IncXPos();
+ }
+ }
+ bmp.End();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+TBuf<16> FooName(TInt aFoo)
+ {
+ TBuf<16> b;
+ b.Format(_L("C:\\pic%d.mbm"), aFoo);
+ return b;
+ }
+
+*/
+
+
+void CDsa::ClipCopy(TUint8* aTarget,
+ const TUint8* aSource,
+ const TRect& aUpdateRect,
+ const TRect& aSourceRect) const
+ {
+ const TDsa dsa(*this);
+ switch(iSourceBpp)
+ {
+ case 1:
+ ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ case 2:
+ ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ case 4:
+ ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ }
+ }
+
+
+void CDsa::Wipe() //dont call in drawing
+ {
+ if(IsDsaAvailable())
+ Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight);
+ }
+
+void CDsa::SetCopyFunction()
+ {
+ //calculate offset to correct function in iCFTable according to given parameters
+ TInt function = 0;
+ const TInt KCopyFunctions = 4;
+ const TInt KOffsetToNative = 0;
+ const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
+ const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
+ const TInt KOffsetTo90Functions = 1;
+ const TInt KOffsetTo180Functions = 2;
+
+ if(iSourceMode == DisplayMode())
+ function = KOffsetToNative; //0
+ else if(iSourceMode == EColor256)
+ function = KOffsetTo256; //4
+ else
+ function = KOffsetToOtherModes; //8
+
+ if(iStateFlags & EOrientation90)
+ function += KOffsetTo90Functions; // + 1
+ if(iStateFlags & EOrientation180)
+ function += KOffsetTo180Functions; //+ 2
+
+ iCopyFunction = iCFTable[function];
+
+ Wipe();
+ }
+
+inline void Rotate(TRect& aRect)
+ {
+ const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
+ const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
+
+ aRect.iBr.iX = aRect.iTl.iX + dy;
+ aRect.iBr.iY = aRect.iTl.iY + dx;
+
+ const TInt tmp = aRect.iTl.iX;
+ aRect.iTl.iX = aRect.iTl.iY;
+ aRect.iTl.iY = tmp;
+ }
+
+/*
+int bar = 0;
+*/
+
+TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
+ {
+
+ if(iStateFlags & EOrientationChanged)
+ {
+ iStateFlags &= ~EOrientationFlags;
+ iStateFlags |= iNewFlags;
+ SetCopyFunction();
+ iStateFlags &= ~EOrientationChanged;
+ EpocSdlEnv::WaitDeviceChange();
+ return EFalse; //skip this frame as data is may be changed
+ }
+
+ if(iTargetAddr == NULL)
+ {
+ iTargetAddr = LockHwSurface();
+ }
+
+ TUint8* target = iTargetAddr;
+ if(target == NULL)
+ return EFalse;
+
+
+ TRect targetRect = TRect(TPoint(0, 0), SwSize());
+
+ TRect sourceRect = aRect;
+ TRect updateRect = aUpdateRect;
+
+// TPoint move(0, 0);
+
+
+ if(iStateFlags & EOrientation90)
+ {
+ Rotate(sourceRect);
+ Rotate(updateRect);
+ }
+
+ if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
+ {
+ sourceRect.Intersection(targetRect); //so source always smaller or equal than target
+ //updateRect.Intersection(targetRect);
+ ClipCopy(target, aBits, updateRect, sourceRect);
+ }
+ else
+ {
+ const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
+ Mem::Copy(target, aBits, byteCount);
+ }
+
+ return ETrue;
+ }
+
+
+void CDsa::UpdateSwSurface()
+ {
+ iTargetAddr = NULL;
+ UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
+ }
+
+
+
+
+void CDsa::DoStop()
+ {
+ if(IsDsaAvailable())
+ iStateFlags |= ESdlThreadExplicitStop;
+ Stop();
+ }
+
+
+void CDsa::Stop()
+ {
+ iStateFlags &= ~ERunning;
+ }
+
+void CDsa::Start()
+ {
+ iStateFlags |= ERunning;
+
+ iStateFlags &= ~ESdlThreadExplicitStop;
+
+ if(iStateFlags & ESdlThreadSuspend)
+ {
+ EpocSdlEnv::Resume();
+ iStateFlags &= ~ ESdlThreadSuspend;
+ }
+ EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
+ }
+
+
+TBool CDsa::Blitter(CFbsBitmap& aBmp)
+ {
+ return iBlitter && iBlitter->BitBlt(Gc(), aBmp, HwRect(), SwSize());
+ }
+
+void CDsa::SetBlitter(MBlitter* aBlitter)
+ {
+ iBlitter = aBlitter;
+ }
+
+
+TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const
+ {
+ TPoint pos = aPoint - iScreenRect.iTl;
+ const TSize asz = iScreenRect.Size();
+ if(iStateFlags & EOrientation180)
+ {
+ pos.iX = asz.iWidth - pos.iX;
+ pos.iY = asz.iHeight - pos.iY;
+ }
+ if(iStateFlags & EOrientation90)
+ {
+ pos.iX = aPoint.iY;
+ pos.iY = aPoint.iX;
+ }
+ pos.iX <<= 16;
+ pos.iY <<= 16;
+ pos.iX /= asz.iWidth;
+ pos.iY /= asz.iHeight;
+ pos.iX *= iSwSize.iWidth;
+ pos.iY *= iSwSize.iHeight;
+ pos.iX >>= 16;
+ pos.iY >>= 16;
+ return pos;
+ }
+
+void CDsa::SetTargetRect()
+ {
+ iTargetRect = iScreenRect;
+ if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
+ {
+ const TSize asz = iScreenRect.Size();
+ const TSize sz = iSwSize;
+
+ TRect rect;
+
+ const TInt dh = (sz.iHeight << 16) / sz.iWidth;
+
+ if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
+ {
+ rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
+ }
+ else
+ {
+ const TInt dw = (sz.iWidth << 16) / sz.iHeight;
+ rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
+ }
+ rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);
+
+ iTargetRect = rect;
+ iTargetRect.Move(iScreenRect.iTl);
+
+ }
+ if(!(iStateFlags & EResizeRequest))
+ iSwSize = iScreenRect.Size();
+
+ }
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
+ Mem::Copy(aTarget, src, aBytes << 2);
+ }
+
+void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *target++ = *column;
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
+ while(target < endt)
+ {
+ *(--endt) = *source++;
+ }
+ }
+
+
+void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *(--endt) = *column;
+ column += aLineLen;
+ }
+ }
+
+/*
+
+LOCAL_C TRgb rgb16MA(TInt aValue)
+ {
+ return TRgb::Color16MA(aValue);
+ }
+*/
+NONSHARABLE_CLASS(MRgbCopy)
+ {
+ public:
+ virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
+ virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
+ };
+
+template <class T>
+NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
+ {
+ public:
+ TRgbCopy(TDisplayMode aMode);
+ void* operator new(TUint aBytes, TAny* aMem);
+ void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
+ void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
+ static TUint32 Gray256(const TUint8& aPixel);
+ static TUint32 Color256(const TUint8& aPixel);
+ static TUint32 Color4K(const TUint16& aPixel);
+ static TUint32 Color64K(const TUint16& aPixel);
+ static TUint32 Color16M(const TUint32& aPixel);
+ static TUint32 Color16MU(const TUint32& aPixel);
+ static TUint32 Color16MA(const TUint32& aPixel);
+ private:
+ typedef TUint32 (*TRgbFunc) (const T& aValue);
+ TRgbFunc iFunc;
+ };
+
+
+template <class T>
+void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
+ {
+ return aMem;
+ }
+
+template <class T>
+TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
+ {
+ switch(aMode)
+ {
+ case EGray256 : iFunc = (TRgbFunc) Gray256; break;
+ case EColor256 : iFunc = (TRgbFunc) Color256; break;
+ case EColor4K : iFunc = (TRgbFunc) Color4K; break;
+ case EColor64K : iFunc = (TRgbFunc) Color64K; break;
+ case EColor16M : iFunc = (TRgbFunc) Color16M; break;
+ case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
+ case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
+ default:
+ PANIC(KErrNotSupported);
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
+ {
+ const T* source = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ const T value = *source++;
+ *(--endt) = iFunc(value);//iFunc(value).Value();
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ const T value = *source++;
+ *target++ = iFunc(value);//iFunc(value).Value();
+ }
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
+ {
+ const T* column = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ *(--endt) = iFunc(*column);
+ column += aLineLen;
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ *target++ = iFunc(*column);
+ column += aLineLen;
+ }
+ }
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
+ {
+ const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
+ return px;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
+ {
+ return TRgb::Color256(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
+ {
+ TUint32 col = (aPixel & 0xF00) << 12;
+ col |= (aPixel & 0xF00) << 8;
+
+ col |= (aPixel & 0x0F0) << 8;
+ col |= (aPixel & 0x0F0);
+
+ col |= (aPixel & 0x00F) << 4;
+ col |= (aPixel & 0x00F);
+
+ return col;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
+ {
+ TUint32 col = (aPixel & 0xF800)<< 8;
+ col |= (aPixel & 0xE000) << 3;
+
+ col |= (aPixel & 0x07E0) << 5;
+ col |= (aPixel & 0xC0) >> 1;
+
+ col |= (aPixel & 0x07E0) << 3;
+ col |= (aPixel & 0x1C) >> 2;
+
+ return col;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
+ {
+ return TRgb::Color16M(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
+ {
+ return TRgb::Color16MU(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
+ {
+ return TRgb::Color16MA(aPixel).Value();
+ }
+
+typedef TUint64 TStackMem;
+
+LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
+ {
+ if(aMode == EColor256 || aMode == EGray256)
+ {
+ return new (mem) TRgbCopy<TUint8>(aMode);
+ }
+ if(aMode == EColor4K || aMode == EColor64K)
+ {
+ return new (mem) TRgbCopy<TUint16>(aMode);
+ }
+ if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
+ {
+ return new (mem) TRgbCopy<TUint32>(aMode);
+ }
+ PANIC(KErrNotSupported);
+ return NULL;
+ }
+
+
+void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);
+ }
+
+void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
+ }
+
+void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);
+ }
+
+void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue);
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////7
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_new.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_new.cpp
new file mode 100644
index 0000000..638fbe8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_new.cpp
@@ -0,0 +1,1443 @@
+#include "dsa.h"
+#include "sdlepocapi.h"
+#include <cdsb.h>
+
+
+LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
+ {
+ return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
+ }
+
+
+NONSHARABLE_CLASS(TDsa)
+ {
+ public:
+ inline TDsa(const CDsa& aDsa);
+ inline TBool IsFlip() const;
+ inline TBool IsTurn() const;
+ inline const TSize& SwSize() const;
+ inline void Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const;
+ private:
+ const CDsa& iDsa;
+ };
+
+
+inline TDsa::TDsa(const CDsa& aDsa) : iDsa(aDsa)
+ {
+ }
+
+inline TBool TDsa::IsTurn() const
+ {
+ return iDsa.iStateFlags & CDsa::EOrientation90;
+ }
+
+inline TBool TDsa::IsFlip() const
+ {
+ return iDsa.iStateFlags & CDsa::EOrientation180;
+ }
+
+inline const TSize& TDsa::SwSize() const
+ {
+ return iDsa.SwSize();
+ }
+
+inline void TDsa::Copy(TUint32* aTarget, const TUint8* aSrc, TInt aBytes, TInt aHeight) const
+ {
+ iDsa.iCopyFunction(iDsa, aTarget, aSrc, aBytes, aHeight);
+ }
+
+template<class T, class S>
+void ClipCopy(const TDsa& iDsa, TUint8* aTarget,
+ const TUint8* aSource,
+ const TRect& aUpdateRect,
+ const TRect& aSourceRect)
+ {
+ const S* source = reinterpret_cast<const S*>(aSource);
+ const TInt lineWidth = aSourceRect.Width();
+
+ source += (aUpdateRect.iTl.iY * lineWidth);
+ const TInt sourceStartOffset = aUpdateRect.iTl.iX;
+ source += sourceStartOffset;
+
+ T* targetPtr = reinterpret_cast<T*>(aTarget);
+
+ const TInt scanLineWidth = iDsa.SwSize().iWidth;
+
+ targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * scanLineWidth;
+ const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
+
+ targetPtr += targetStartOffset;
+
+
+ const TInt height = aUpdateRect.Height();
+
+ const TInt lineMove = iDsa.IsTurn() ? 1 : lineWidth;
+ const TInt copyLen = aUpdateRect.Width();
+
+
+ if(iDsa.IsFlip())
+ {
+
+ targetPtr += scanLineWidth * (height - 1);
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
+ source += lineMove;
+ targetPtr -= scanLineWidth;
+ }
+ }
+ else
+ {
+
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iDsa.Copy(reinterpret_cast<TUint32*>(targetPtr), reinterpret_cast<const TUint8*>(source), copyLen, height);
+ source += lineMove;
+ targetPtr += scanLineWidth; // >> 2;
+ }
+ }
+
+ }
+
+
+
+NONSHARABLE_CLASS(CDsaA) : public CDsa
+ {
+ public:
+ CDsaA(RWsSession& aSession);
+ private:
+ ~CDsaA();
+ TUint8* LockSurface();
+ void UnlockHWSurfaceRequestComplete();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void Free();
+ void Update(CFbsBitmap& aBmp);
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ TInt ExternalUpdate();
+ // void ExternalUpdate();
+ protected:
+ CFbsBitmap* iBmp;
+ CFbsBitmap* iCopyBmp;
+ };
+
+
+CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
+ {
+ }
+
+
+void CDsaA::Free()
+ {
+ delete iBmp;
+ iBmp = NULL;
+ }
+
+CDsaA::~CDsaA()
+ {
+ __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
+ delete iCopyBmp;
+ }
+
+TUint8* CDsaA::LockSurface()
+ {
+ iBmp->LockHeap();
+ return reinterpret_cast<TUint8*>(iBmp->DataAddress());
+ }
+
+void CDsaA::UnlockHWSurfaceRequestComplete()
+ {
+ PANIC(KErrNotSupported);
+ }
+
+void CDsaA::UnlockHwSurface()
+ {
+ iBmp->UnlockHeap();
+ SetUpdating(EFalse);
+ Update(*iBmp);
+ }
+
+void CDsaA::Update(CFbsBitmap& aBmp)
+ {
+ if(!Blitter(aBmp))
+ {
+ if(SwSize() == HwRect().Size())
+ Dsa().Gc()->BitBlt(HwRect().iTl, &aBmp);
+ else
+ Dsa().Gc()->DrawBitmap(HwRect(), &aBmp);
+ }
+ DrawOverlays();
+ Dsa().ScreenDevice()->Update();
+ }
+void CDsaA::CreateSurfaceL()
+ {
+ delete iBmp;
+ iBmp = NULL;
+ iBmp = new (ELeave) CFbsBitmap();
+ User::LeaveIfError(iBmp->Create(SwSize(), DisplayMode()));
+ }
+
+void CDsaA::Wipe(TInt aLength) //dont call in drawing
+ {
+ iBmp->LockHeap();
+ Mem::FillZ(iBmp->DataAddress(), aLength);
+ iBmp->UnlockHeap();
+ }
+
+
+
+TInt CDsaA::ExternalUpdate()
+ {
+ if(iCopyBmp->Handle() == 0)
+ {
+ const TInt err = iCopyBmp->Duplicate(iBmp->Handle());
+ if(err != KErrNone)
+ return err;
+ }
+ Update(*iCopyBmp);
+ return KErrNone;
+ }
+
+void CDsaA::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ iCopyBmp = new (ELeave) CFbsBitmap();
+ CDsa::ConstructL(aWindow, aDevice);
+ }
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+NONSHARABLE_CLASS(MDsbObs)
+ {
+ public:
+ virtual void SurfaceReady() = 0;
+ virtual CDirectScreenBitmap& Dsb() = 0;
+ };
+
+NONSHARABLE_CLASS(CDsbSurface) : public CActive
+ {
+ public:
+ CDsbSurface(MDsbObs& aDsb);
+ TUint8* Address();
+ void Complete();
+ ~CDsbSurface();
+ private:
+ void RunL();
+ void DoCancel();
+ private:
+ MDsbObs& iDsb;
+ TUint8* iAddress;
+ };
+
+CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CDsbSurface::~CDsbSurface()
+ {
+ Cancel();
+ }
+
+void CDsbSurface::Complete()
+ {
+ if(iAddress != NULL && !IsActive())
+ {
+ iAddress = NULL;
+ SetActive();
+ iDsb.Dsb().EndUpdate(iStatus);
+ }
+ }
+
+TUint8* CDsbSurface::Address()
+ {
+ if(iAddress == NULL && !IsActive())
+ {
+ TAcceleratedBitmapInfo info;
+ if(KErrNone == iDsb.Dsb().BeginUpdate(info))
+ iAddress = info.iAddress;
+ }
+ return iAddress;
+ }
+
+void CDsbSurface::RunL()
+ {
+ iDsb.SurfaceReady();
+ }
+
+void CDsbSurface::DoCancel()
+ {
+ //empty
+ }
+
+NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs
+ {
+ public:
+ CDsaB(RWsSession& aSession, TInt aFlags);
+ private:
+ ~CDsaB();
+ TUint8* LockSurface();
+ void UnlockHWSurfaceRequestComplete();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void RecreateL();
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ CDirectScreenBitmap& Dsb();
+ void SurfaceReady();
+ TInt ExternalUpdate();
+ private:
+ CDsbSurface* iSurface1;
+ CDsbSurface* iSurface2;
+ CDirectScreenBitmap* iDsb;
+ TInt iType;
+ };
+
+CDsaB::CDsaB(RWsSession& aSession, TInt aFlags) : CDsa(aSession), iType(aFlags)
+ {
+ }
+
+
+
+void CDsaB::UnlockHWSurfaceRequestComplete()
+ {
+ iSurface1->Complete();
+ if(iSurface2 != NULL)
+ iSurface2->Complete();
+ }
+
+void CDsaB::CreateSurfaceL()
+ {
+ __ASSERT_ALWAYS(SwSize() == HwRect().Size(), PANIC(KErrNotSupported));
+ }
+
+void CDsaB::Wipe(TInt aLength) //dont call in drawing
+ {
+ TUint8* addr = LockSurface();
+ if(addr != NULL)
+ {
+ Mem::FillZ(addr, aLength);
+ UnlockHwSurface();
+ }
+ }
+
+
+void CDsaB::UnlockHwSurface()
+ {
+ EpocSdlEnv::Request(CDsa::ERequestUpdate);
+ }
+
+TUint8* CDsaB::LockSurface()
+ {
+ TUint8* addr = iSurface1->Address();
+ if(addr == NULL && iSurface2 != NULL)
+ addr = iSurface2->Address();
+ SetUpdating(addr == NULL);
+ return addr;
+ }
+
+void CDsaB::SurfaceReady()
+ {
+ SetUpdating(EFalse);
+ }
+
+CDirectScreenBitmap& CDsaB::Dsb()
+ {
+ return *iDsb;
+ }
+
+void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ if(iDsb == NULL)
+ iDsb = CDirectScreenBitmap::NewL();
+ CDsa::ConstructL(aWindow, aDevice);
+ if(iSurface1 == NULL)
+ iSurface1 = new (ELeave) CDsbSurface(*this);
+ if(iSurface2 == NULL && iType & CDirectScreenBitmap::EDoubleBuffer)
+ iSurface2 = new (ELeave) CDsbSurface(*this);
+ }
+
+CDsaB::~CDsaB()
+ {
+ delete iSurface1;
+ delete iSurface2;
+ delete iDsb;
+ }
+
+void CDsaB::RecreateL()
+ {
+ iDsb->Close();
+ iDsb->Create(HwRect(), CDirectScreenBitmap::TSettingsFlags(iType));
+ }
+
+TInt CDsaB::ExternalUpdate()
+ {
+ if(LockSurface())
+ {
+ UnlockHWSurfaceRequestComplete();
+ return KErrNone;
+ }
+ return KErrNotReady;
+ }
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+CDsa* CDsa::CreateL(RWsSession& aSession)
+ {
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
+ {
+ TInt flags = CDirectScreenBitmap::ENone;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
+ flags |= CDirectScreenBitmap::EDoubleBuffer;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate))
+ flags |= CDirectScreenBitmap::EIncrementalUpdate;
+ return new (ELeave) CDsaB(aSession, flags);
+ }
+ else
+ return new (ELeave) CDsaA(aSession);
+ }
+
+
+void CDsa::RecreateL()
+ {
+ }
+
+void CDsa::Free()
+ {
+ }
+
+TSize CDsa::WindowSize() const
+ {
+ TSize size = iSwSize;
+ if(iStateFlags & EOrientation90)
+ {
+ const TInt tmp = size.iWidth;
+ size.iWidth = size.iHeight;
+ size.iHeight = tmp;
+ }
+ return size;
+ }
+
+void CDsa::SetSuspend()
+ {
+ iStateFlags |= ESdlThreadSuspend;
+ }
+
+void CDsa::ReleaseStop()
+ {
+ iStateFlags &= ~ESdlThreadExplicitStop;
+ }
+
+
+TBool CDsa::Stopped() const
+ {
+ return (iStateFlags & ESdlThreadExplicitStop);
+ }
+
+void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
+ {
+ TInt flags = 0;
+ switch(aOrientation)
+ {
+ case CSDL::EOrientation90:
+ flags = EOrientation90;
+ break;
+ case CSDL::EOrientation180:
+ flags = EOrientation180;
+ break;
+ case CSDL::EOrientation270:
+ flags = EOrientation90 | EOrientation180;
+ break;
+ case CSDL::EOrientation0:
+ flags = 0;
+ break;
+ }
+ if(flags != (iStateFlags & EOrientationFlags))
+ {
+ iStateFlags |= EOrientationChanged;
+ iNewFlags = flags; //cannot be set during drawing...
+ }
+ }
+
+CDsa::~CDsa()
+ {
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ }
+ iOverlays.Close();
+ delete iDsa;
+ User::Free(iLut256);
+ }
+
+void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ delete iDsa;
+ iDsa = NULL;
+ }
+
+ iDsa = CDirectScreenAccess::NewL(
+ iSession,
+ aDevice,
+ aWindow,
+ *this);
+
+ if(iLut256 == NULL)
+ iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
+ iTargetMode = aWindow.DisplayMode();
+ iTargetBpp = BytesPerPixel(DisplayMode());
+ iScreenRect = TRect(aWindow.Position(), aWindow.Size());
+ SetTargetRect();
+ RestartL();
+ }
+
+void CDsa::DrawOverlays()
+ {
+ const TInt last = iOverlays.Count() - 1;
+ for(TInt i = last; i >= 0 ; i--)
+ iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize());
+ }
+
+TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
+ {
+ TInt i;
+ for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
+ {}
+ const TOverlay overlay = {&aOverlay, aPriority};
+ return iOverlays.Insert(overlay, i);
+ }
+
+TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
+ {
+ for(TInt i = 0; i < iOverlays.Count(); i++)
+ {
+ if(iOverlays[i].iOverlay == &aOverlay)
+ {
+ iOverlays.Remove(i);
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+void CDsa::LockPalette(TBool aLock)
+ {
+ if(aLock)
+ iStateFlags |= EPaletteLocked;
+ else
+ iStateFlags &= ~EPaletteLocked;
+ }
+TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
+ {
+ if(iLut256 == NULL)
+ return KErrNotFound;
+ const TInt count = aCount - aFirst;
+ if(count > 256)
+ return KErrArgument;
+ if(iStateFlags & EPaletteLocked)
+ return KErrNone;
+ for(TInt i = aFirst; i < count; i++) //not so busy here:-)
+ {
+ iLut256[i] = aPalette[i];
+ }
+ return KErrNone;
+ }
+
+
+
+void CDsa::RestartL()
+ {
+ //const TBool active = iDsa->IsActive();
+
+ //if(!active)
+
+ iDsa->StartL();
+
+ const RRegion* r = iDsa->DrawingRegion();
+ const TRect rect = r->BoundingRect();
+ iDsa->Gc()->SetClippingRegion(r);
+
+ if(rect != iScreenRect)
+ {
+ // iDsa->Cancel();
+ return ;
+ }
+
+
+
+ //iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip
+ //targetrect shall no change
+ SetTargetRect();
+ RecreateL();
+
+ iStateFlags |= ERunning;
+
+ ReleaseStop();
+ if(iStateFlags & ESdlThreadSuspend)
+ {
+ EpocSdlEnv::Resume();
+ iStateFlags &= ~ ESdlThreadSuspend;
+ }
+ EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
+ }
+
+CDsa::CDsa(RWsSession& aSession) :
+ iSession(aSession),
+ iStateFlags(0)
+ {
+// CActiveScheduler::Add(this);
+ iCFTable[0] = CopyMem;
+ iCFTable[1] = CopyMemFlipReversed;
+ iCFTable[2] = CopyMemReversed;
+ iCFTable[3] = CopyMemFlip;
+
+ iCFTable[4] = Copy256;
+ iCFTable[5] = Copy256FlipReversed;
+ iCFTable[6] = Copy256Reversed;
+ iCFTable[7] = Copy256Flip;
+
+
+ iCFTable[8] = CopySlow;
+ iCFTable[9] = CopySlowFlipReversed;
+ iCFTable[10] = CopySlowReversed;
+ iCFTable[11] = CopySlowFlip;
+ }
+
+RWsSession& CDsa::Session()
+ {
+ return iSession;
+ }
+
+TInt CDsa::RedrawRequest()
+ {
+ if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
+ {
+ return ExternalUpdate();
+ }
+ return KErrNotReady;
+ }
+
+TUint8* CDsa::LockHwSurface()
+ {
+ if((iStateFlags & EUpdating) == 0) //else frame is skipped
+ {
+ return LockSurface();
+ }
+ return NULL;
+ }
+
+/*
+void CDsa::RunL()
+ {
+ iStateFlags &= ~EUpdating;
+ }
+
+
+void CDsa::DoCancel()
+ {
+ iStateFlags &= ~EUpdating;
+ //nothing can do, just wait?
+ }
+*/
+
+
+TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
+ {
+ if(aHwSurface && aMode != DisplayMode())
+ return KErrArgument;
+
+ iSourceMode = aMode;
+
+ iSourceBpp = BytesPerPixel(aMode);
+
+ const TSize size = WindowSize();
+ if(aSize.iWidth > size.iWidth)
+ return KErrTooBig;
+ if(aSize.iHeight > size.iHeight)
+ return KErrTooBig;
+
+ TRAPD(err, CreateSurfaceL());
+ if(err != KErrNone)
+ return err;
+
+ SetCopyFunction();
+
+ return KErrNone;
+ }
+
+
+void CDsa::CreateZoomerL(const TSize& aSize)
+ {
+ iSwSize = aSize;
+ iStateFlags |= EResizeRequest;
+ CreateSurfaceL();
+ SetTargetRect();
+ }
+
+
+/*
+void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, aMode);
+ s->LockHeap();
+ TUint32* addr = s->DataAddress();
+ Mem::Copy(addr, aData, aLength);
+ s->UnlockHeap();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, EColor64K);
+ TBitmapUtil bmp(s);
+ bmp.Begin(TPoint(0, 0));
+ for(TInt j = 0; j < aSz.iHeight; j++)
+ {
+ bmp.SetPos(TPoint(0, j));
+ for(TInt i = 0; i < aSz.iWidth; i++)
+ {
+ bmp.SetPixel(*aData);
+ aData++;
+ bmp.IncXPos();
+ }
+ }
+ bmp.End();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+TBuf<16> FooName(TInt aFoo)
+ {
+ TBuf<16> b;
+ b.Format(_L("C:\\pic%d.mbm"), aFoo);
+ return b;
+ }
+
+void ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos)
+ {
+ const TInt iSourceBpp = 1;
+ const TInt iTargetBpp = 4;
+ const TInt iScanLineWidth = 800;
+
+ TUint8* target = aTarget;
+ const TUint8* source = aSource;
+ const TInt lineWidth = aRect.Width();
+ source += iSourceBpp * (aRect.iTl.iY * lineWidth);
+ const TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX;
+ source += sourceStartOffset;
+ target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth);
+ const TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
+ target += targetStartOffset;
+ TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
+ const TInt targetWidth = iScanLineWidth >> 2;
+ const TInt height = aRect.Height();
+ }
+*/
+/*
+void CDsa::ClipCopy(TUint8* aTarget,
+ const TUint8* aSource,
+ const TRect& aUpdateRect,
+ const TRect& aSourceRect) const
+ {
+ //TUint8* target = aTarget;
+ const TUint32* source = (const TUint32*) aSource;
+ const TInt lineWidth = aSourceRect.Width();
+
+ source += (aUpdateRect.iTl.iY * lineWidth);
+ const TInt sourceStartOffset = aUpdateRect.iTl.iX;
+ source += sourceStartOffset;
+
+ TUint32* targetPtr = reinterpret_cast<TUint32*>(aTarget);
+
+ targetPtr += (aSourceRect.iTl.iY + aUpdateRect.iTl.iY ) * SwSize().iWidth;
+ const TInt targetStartOffset = (aUpdateRect.iTl.iX + aSourceRect.iTl.iX);
+
+ targetPtr += targetStartOffset;
+
+// TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
+
+ const TInt targetWidth32 = SwSize().iWidth;
+
+ const TInt height = aUpdateRect.Height();
+
+ const TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
+ const TInt copyLen = aUpdateRect.Width();
+
+
+ if(iStateFlags & EOrientation180)
+ {
+
+ targetPtr += targetWidth32 * (height - 1);
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
+ source += lineMove;
+ targetPtr -= targetWidth32;
+ }
+ }
+ else
+ {
+
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, (TUint8*)source, copyLen, height);
+ source += lineMove;
+ targetPtr += targetWidth32; // >> 2;
+ }
+ }
+
+ }
+
+*/
+
+void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TPoint& aTargetPos) const
+ {
+ TUint8* target = aTarget;
+ const TUint8* source = aSource;
+ const TInt lineWidth = aRect.Width();
+ source += iSourceBpp * (aRect.iTl.iY * lineWidth);
+ TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX;
+ source += sourceStartOffset;
+ target += iTargetBpp * ((aTargetPos.iY + aRect.iTl.iY ) * lineWidth);
+ TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iX);
+ target += targetStartOffset;
+ TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
+ const TInt targetWidth = iScanLineWidth >> 2;
+ const TInt height = aRect.Height();
+
+ TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
+
+ if(iStateFlags & EOrientation180)
+ {
+
+ targetPtr += targetWidth * (height - 1);
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, source, lineWidth, height);
+ source += lineMove;
+ targetPtr -= targetWidth;
+ }
+ }
+ else
+ {
+
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, source, lineWidth, height);
+ source += lineMove;
+ targetPtr += targetWidth;
+ }
+ }
+
+ }
+
+
+
+ /*
+void CDsa::ClipCopy(TUint8* aTarget,
+ const TUint8* aSource,
+ const TRect& aUpdateRect,
+ const TRect& aSourceRect) const
+ {
+ const TDsa dsa(*this);
+ switch(iSourceBpp)
+ {
+ case 1:
+ ::ClipCopy<TUint32, TUint8>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ case 2:
+ ::ClipCopy<TUint32, TUint16>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ case 4:
+ ::ClipCopy<TUint32, TUint32>(dsa, aTarget, aSource, aUpdateRect, aSourceRect);
+ break;
+ }
+ }
+
+
+*/
+
+
+
+void CDsa::Wipe() //dont call in drawing
+ {
+ if(IsDsaAvailable())
+ Wipe(iTargetBpp * SwSize().iWidth * SwSize().iHeight);
+ }
+
+void CDsa::SetCopyFunction()
+ {
+ //calculate offset to correct function in iCFTable according to given parameters
+ TInt function = 0;
+ const TInt KCopyFunctions = 4;
+ const TInt KOffsetToNative = 0;
+ const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
+ const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
+ const TInt KOffsetTo90Functions = 1;
+ const TInt KOffsetTo180Functions = 2;
+
+ if(iSourceMode == DisplayMode())
+ function = KOffsetToNative; //0
+ else if(iSourceMode == EColor256)
+ function = KOffsetTo256; //4
+ else
+ function = KOffsetToOtherModes; //8
+
+ if(iStateFlags & EOrientation90)
+ function += KOffsetTo90Functions; // + 1
+ if(iStateFlags & EOrientation180)
+ function += KOffsetTo180Functions; //+ 2
+
+ iCopyFunction = iCFTable[function];
+
+ Wipe();
+ }
+
+inline void Rotate(TRect& aRect)
+ {
+ const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
+ const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
+
+ aRect.iBr.iX = aRect.iTl.iX + dy;
+ aRect.iBr.iY = aRect.iTl.iY + dx;
+
+ const TInt tmp = aRect.iTl.iX;
+ aRect.iTl.iX = aRect.iTl.iY;
+ aRect.iTl.iY = tmp;
+ }
+
+/*
+int bar = 0;
+*/
+/*
+TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
+ {
+
+ if(iStateFlags & EOrientationChanged)
+ {
+ iStateFlags &= ~EOrientationFlags;
+ iStateFlags |= iNewFlags;
+ SetCopyFunction();
+ iStateFlags &= ~EOrientationChanged;
+ EpocSdlEnv::WaitDeviceChange();
+ return EFalse; //skip this frame as data is may be changed
+ }
+
+ if(iTargetAddr == NULL)
+ {
+ iTargetAddr = LockHwSurface();
+ }
+
+ TUint8* target = iTargetAddr;
+ if(target == NULL)
+ return EFalse;
+
+
+ TRect targetRect = TRect(TPoint(0, 0), SwSize());
+
+ TRect sourceRect = aRect;
+ TRect updateRect = aUpdateRect;
+
+// TPoint move(0, 0);
+
+
+ if(iStateFlags & EOrientation90)
+ {
+ Rotate(sourceRect);
+ Rotate(updateRect);
+ }
+
+ if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
+ {
+ sourceRect.Intersection(targetRect); //so source always smaller or equal than target
+ //updateRect.Intersection(targetRect);
+ ClipCopy(target, aBits, updateRect, sourceRect);
+ }
+ else
+ {
+ const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
+ Mem::Copy(target, aBits, byteCount);
+ }
+
+ return ETrue;
+ }
+ */
+
+TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
+ {
+
+ if(iStateFlags & EOrientationChanged)
+ {
+ iStateFlags &= ~EOrientationFlags;
+ iStateFlags |= iNewFlags;
+ SetCopyFunction();
+ iStateFlags &= ~EOrientationChanged;
+ EpocSdlEnv::WaitDeviceChange();
+ return EFalse; //skip this frame as data is may be changed
+ }
+
+ if(iTargetAddr == NULL)
+ {
+ iTargetAddr = LockHwSurface();
+ }
+ TUint8* target = iTargetAddr;
+ if(target == NULL)
+ return EFalse;
+
+
+ TRect targetRect = Rect();
+ TRect sourceRect = aRect;
+ TRect updateRect = aUpdateRect;
+
+ if(iStateFlags & EOrientation90)
+ {
+ Rotate(sourceRect);
+ Rotate(updateRect);
+ }
+
+ if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
+ {
+ sourceRect.Intersection(targetRect); //so source always smaller or equal than target
+ updateRect.Intersection(targetRect);
+ ClipCopy(target, aBits, updateRect, sourceRect.iTl);
+ }
+ else
+ {
+ const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
+ Mem::Copy(target, aBits, byteCount);
+ }
+
+ return ETrue;
+ }
+void CDsa::UpdateSwSurface()
+ {
+ iTargetAddr = NULL;
+ UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
+ }
+
+
+void CDsa::Resume()
+ {
+ if(Stopped())
+ Restart(RDirectScreenAccess::ETerminateRegion);
+ }
+
+void CDsa::DoStop()
+ {
+ if(IsDsaAvailable())
+ iStateFlags |= ESdlThreadExplicitStop;
+ Stop();
+ }
+
+void CDsa::Stop()
+ {
+ iStateFlags &= ~ERunning;
+// Cancel(); //can be called only from main!
+ iDsa->Cancel();
+ }
+
+void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
+ {
+// iStateFlags |= EChangeNotify;
+ Stop();
+ }
+
+void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason)
+ {
+ if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
+ {
+ TRAPD(err, RestartL());
+ PANIC_IF_ERROR(err);
+ }
+ }
+
+void CDsa::SetBlitter(MBlitter* aBlitter)
+ {
+ iBlitter = aBlitter;
+ }
+
+
+TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const
+ {
+ TPoint pos = aPoint - iScreenRect.iTl;
+ const TSize asz = iScreenRect.Size();
+ if(iStateFlags & EOrientation180)
+ {
+ pos.iX = asz.iWidth - pos.iX;
+ pos.iY = asz.iHeight - pos.iY;
+ }
+ if(iStateFlags & EOrientation90)
+ {
+ pos.iX = aPoint.iY;
+ pos.iY = aPoint.iX;
+ }
+ pos.iX <<= 16;
+ pos.iY <<= 16;
+ pos.iX /= asz.iWidth;
+ pos.iY /= asz.iHeight;
+ pos.iX *= iSwSize.iWidth;
+ pos.iY *= iSwSize.iHeight;
+ pos.iX >>= 16;
+ pos.iY >>= 16;
+ return pos;
+ }
+
+void CDsa::SetTargetRect()
+ {
+ iTargetRect = iScreenRect;
+ if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
+ {
+ const TSize asz = iScreenRect.Size();
+ const TSize sz = iSwSize;
+
+ TRect rect;
+
+ const TInt dh = (sz.iHeight << 16) / sz.iWidth;
+
+ if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
+ {
+ rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
+ }
+ else
+ {
+ const TInt dw = (sz.iWidth << 16) / sz.iHeight;
+ rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
+ }
+ rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);
+
+ iTargetRect = rect;
+ iTargetRect.Move(iScreenRect.iTl);
+
+ }
+ if(!(iStateFlags & EResizeRequest))
+ iSwSize = iScreenRect.Size();
+// iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth;
+ }
+
+/*)
+TBool CDsa::ChangeTrigger()
+ {
+ const TBool change = iStateFlags & EChangeNotify;
+ iStateFlags &= ~EChangeNotify;
+ return change;
+ }
+*/
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* src = reinterpret_cast<const TUint32*>(aSource);
+ Mem::Copy(aTarget, src, aBytes << 2);
+ }
+
+void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *target++ = *column;
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
+ while(target < endt)
+ {
+ *(--endt) = *source++;
+ }
+ }
+
+
+void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *(--endt) = *column;
+ column += aLineLen;
+ }
+ }
+
+/*
+
+LOCAL_C TRgb rgb16MA(TInt aValue)
+ {
+ return TRgb::Color16MA(aValue);
+ }
+*/
+NONSHARABLE_CLASS(MRgbCopy)
+ {
+ public:
+ virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
+ virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
+ };
+
+template <class T>
+NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
+ {
+ public:
+ TRgbCopy(TDisplayMode aMode);
+ void* operator new(TUint aBytes, TAny* aMem);
+ void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
+ void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
+ static TUint32 Gray256(const TUint8& aPixel);
+ static TUint32 Color256(const TUint8& aPixel);
+ static TUint32 Color4K(const TUint16& aPixel);
+ static TUint32 Color64K(const TUint16& aPixel);
+ static TUint32 Color16M(const TUint32& aPixel);
+ static TUint32 Color16MU(const TUint32& aPixel);
+ static TUint32 Color16MA(const TUint32& aPixel);
+ private:
+ typedef TUint32 (*TRgbFunc) (const T& aValue);
+ TRgbFunc iFunc;
+ };
+
+
+template <class T>
+void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
+ {
+ return aMem;
+ }
+
+template <class T>
+TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
+ {
+ switch(aMode)
+ {
+ case EGray256 : iFunc = (TRgbFunc) Gray256; break;
+ case EColor256 : iFunc = (TRgbFunc) Color256; break;
+ case EColor4K : iFunc = (TRgbFunc) Color4K; break;
+ case EColor64K : iFunc = (TRgbFunc) Color64K; break;
+ case EColor16M : iFunc = (TRgbFunc) Color16M; break;
+ case EColor16MU : iFunc = (TRgbFunc) Color16MU; break;
+ case EColor16MA : iFunc = (TRgbFunc) Color16MA; break;
+ default:
+ PANIC(KErrNotSupported);
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
+ {
+ const T* source = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ const T value = *source++;
+ *(--endt) = iFunc(value);//iFunc(value).Value();
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ const T value = *source++;
+ *target++ = iFunc(value);//iFunc(value).Value();
+ }
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
+ {
+ const T* column = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ *(--endt) = iFunc(*column);
+ column += aLineLen;
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ *target++ = iFunc(*column);
+ column += aLineLen;
+ }
+ }
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Gray256(const TUint8& aPixel)
+ {
+ const TUint32 px = aPixel << 16 | aPixel << 8 | aPixel;
+ return px;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color256(const TUint8& aPixel)
+ {
+ return TRgb::Color256(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color4K(const TUint16& aPixel)
+ {
+ TUint32 col = (aPixel & 0xF00) << 12;
+ col |= (aPixel & 0xF00) << 8;
+
+ col |= (aPixel & 0x0F0) << 8;
+ col |= (aPixel & 0x0F0);
+
+ col |= (aPixel & 0x00F) << 4;
+ col |= (aPixel & 0x00F);
+
+ return col;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color64K(const TUint16& aPixel)
+ {
+ TUint32 col = (aPixel & 0xF800)<< 8;
+ col |= (aPixel & 0xE000) << 3;
+
+ col |= (aPixel & 0x07E0) << 5;
+ col |= (aPixel & 0xC0) >> 1;
+
+ col |= (aPixel & 0x07E0) << 3;
+ col |= (aPixel & 0x1C) >> 2;
+
+ return col;
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16M(const TUint32& aPixel)
+ {
+ return TRgb::Color16M(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16MU(const TUint32& aPixel)
+ {
+ return TRgb::Color16MU(aPixel).Value();
+ }
+
+template <class T> TUint32 TRgbCopy<T>::Color16MA(const TUint32& aPixel)
+ {
+ return TRgb::Color16MA(aPixel).Value();
+ }
+
+typedef TUint64 TStackMem;
+
+LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
+ {
+ if(aMode == EColor256 || aMode == EGray256)
+ {
+ return new (mem) TRgbCopy<TUint8>(aMode);
+ }
+ if(aMode == EColor4K || aMode == EColor64K)
+ {
+ return new (mem) TRgbCopy<TUint16>(aMode);
+ }
+ if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
+ {
+ return new (mem) TRgbCopy<TUint32>(aMode);
+ }
+ PANIC(KErrNotSupported);
+ return NULL;
+ }
+
+
+void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);
+ }
+
+void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
+ }
+
+void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);
+ }
+
+void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue);
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////7
diff --git a/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_old.cpp b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_old.cpp
new file mode 100644
index 0000000..7e32de2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/EKA2/dsa_old.cpp
@@ -0,0 +1,1075 @@
+#include "dsa.h"
+#include "sdlepocapi.h"
+#include <cdsb.h>
+
+LOCAL_C TInt BytesPerPixel(TDisplayMode aMode)
+ {
+ return ((TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode) - 1) >> 3) + 1;
+ }
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+NONSHARABLE_CLASS(CDsaA) : public CDsa
+ {
+ public:
+ CDsaA(RWsSession& aSession);
+ private:
+ ~CDsaA();
+ TUint8* LockSurface();
+ void UnlockHWSurfaceRequestComplete();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void RecreateL();
+ void Free();
+ TInt ExternalUpdate() {return 0;}
+ private:
+ CFbsBitmap* iBmp;
+ };
+
+
+CDsaA::CDsaA(RWsSession& aSession) : CDsa(aSession)
+ {
+ }
+
+void CDsaA::Free()
+ {
+ delete iBmp;
+ iBmp = NULL;
+ }
+
+CDsaA::~CDsaA()
+ {
+ __ASSERT_DEBUG(iBmp == NULL, PANIC(KErrNotReady));
+ }
+
+TUint8* CDsaA::LockSurface()
+ {
+ iBmp->LockHeap();
+ return reinterpret_cast<TUint8*>(iBmp->DataAddress());
+ }
+
+void CDsaA::UnlockHWSurfaceRequestComplete()
+ {
+ PANIC(KErrNotSupported);
+ }
+
+void CDsaA::UnlockHwSurface()
+ {
+ iBmp->UnlockHeap();
+ SetUpdating(EFalse);
+ Dsa().Gc()->BitBlt(HwRect().iTl, iBmp);
+ Dsa().ScreenDevice()->Update();
+ }
+
+void CDsaA::CreateSurfaceL()
+ {
+ delete iBmp;
+ iBmp = NULL;
+ iBmp = new (ELeave) CFbsBitmap();
+ User::LeaveIfError(iBmp->Create(HwRect().Size(), DisplayMode()));
+ }
+
+void CDsaA::Wipe(TInt aLength) //dont call in drawing
+ {
+ iBmp->LockHeap();
+ Mem::FillZ(iBmp->DataAddress(), aLength);
+ iBmp->UnlockHeap();
+ }
+
+void CDsaA::RecreateL()
+ {
+ }
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+NONSHARABLE_CLASS(MDsbObs)
+ {
+ public:
+ virtual void SurfaceReady() = 0;
+ virtual CDirectScreenBitmap& Dsb() = 0;
+ };
+
+NONSHARABLE_CLASS(CDsbSurface) : public CActive
+ {
+ public:
+ CDsbSurface(MDsbObs& aDsb);
+ TUint8* Address();
+ void Complete();
+ ~CDsbSurface();
+ private:
+ void RunL();
+ void DoCancel();
+ private:
+ MDsbObs& iDsb;
+ TUint8* iAddress;
+ };
+
+CDsbSurface::CDsbSurface(MDsbObs& aDsb) : CActive(CActive::EPriorityHigh) , iDsb(aDsb)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CDsbSurface::~CDsbSurface()
+ {
+ Cancel();
+ }
+
+void CDsbSurface::Complete()
+ {
+ if(iAddress != NULL && !IsActive())
+ {
+ iAddress = NULL;
+ SetActive();
+ iDsb.Dsb().EndUpdate(iStatus);
+ }
+ }
+
+TUint8* CDsbSurface::Address()
+ {
+ if(iAddress == NULL && !IsActive())
+ {
+ TAcceleratedBitmapInfo info;
+ if(KErrNone == iDsb.Dsb().BeginUpdate(info))
+ iAddress = info.iAddress;
+ }
+ return iAddress;
+ }
+
+void CDsbSurface::RunL()
+ {
+ iDsb.SurfaceReady();
+ }
+
+void CDsbSurface::DoCancel()
+ {
+ //empty
+ }
+
+NONSHARABLE_CLASS(CDsaB) : public CDsa, public MDsbObs
+ {
+ public:
+ CDsaB(RWsSession& aSession);
+ private:
+ ~CDsaB();
+ TUint8* LockSurface();
+ void UnlockHWSurfaceRequestComplete();
+ void UnlockHwSurface();
+ void CreateSurfaceL();
+ void Wipe(TInt aLength);
+ void RecreateL();
+ void ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice);
+ void Free();
+ CDirectScreenBitmap& Dsb();
+ void SurfaceReady();
+ TInt ExternalUpdate() {return 0;}
+ private:
+ CDsbSurface* iSurface1;
+ CDsbSurface* iSurface2;
+ CDirectScreenBitmap* iDsb;
+ };
+
+CDsaB::CDsaB(RWsSession& aSession) : CDsa(aSession)
+ {
+ }
+
+void CDsaB::Free()
+ {
+ }
+
+void CDsaB::UnlockHWSurfaceRequestComplete()
+ {
+ iSurface1->Complete();
+ iSurface2->Complete();
+ }
+
+void CDsaB::CreateSurfaceL()
+ {
+ }
+
+void CDsaB::Wipe(TInt aLength) //dont call in drawing
+ {
+ TUint8* addr = LockSurface();
+ if(addr != NULL)
+ {
+ Mem::FillZ(addr, aLength);
+ UnlockHwSurface();
+ }
+ }
+
+void CDsaB::UnlockHwSurface()
+ {
+ EpocSdlEnv::Request(CDsa::ERequestUpdate);
+ }
+
+TUint8* CDsaB::LockSurface()
+ {
+ TUint8* addr = iSurface1->Address();
+ if(addr == NULL)
+ addr = iSurface2->Address();
+ SetUpdating(addr == NULL);
+ return addr;
+ }
+
+void CDsaB::SurfaceReady()
+ {
+ SetUpdating(EFalse);
+ }
+
+CDirectScreenBitmap& CDsaB::Dsb()
+ {
+ return *iDsb;
+ }
+
+void CDsaB::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ if(iDsb == NULL)
+ iDsb = CDirectScreenBitmap::NewL();
+ CDsa::ConstructL(aWindow, aDevice);
+ iSurface1 = new (ELeave) CDsbSurface(*this);
+ iSurface2 = new (ELeave) CDsbSurface(*this);
+ }
+
+CDsaB::~CDsaB()
+ {
+ delete iSurface1;
+ delete iSurface2;
+ delete iDsb;
+ }
+
+void CDsaB::RecreateL()
+ {
+ iDsb->Close();
+ iDsb->Create(HwRect(), CDirectScreenBitmap::EDoubleBuffer);
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+TSize CDsa::WindowSize() const
+ {
+ TSize size = HwRect().Size();
+ if(iStateFlags & EOrientation90)
+ {
+ const TInt tmp = size.iWidth;
+ size.iWidth = size.iHeight;
+ size.iHeight = tmp;
+ }
+ return size;
+ }
+
+void CDsa::SetSuspend()
+ {
+ iStateFlags |= ESdlThreadSuspend;
+ }
+
+void CDsa::ReleaseStop()
+ {
+ iStateFlags &= ~ESdlThreadExplicitStop;
+ }
+
+
+TBool CDsa::Stopped() const
+ {
+ return (iStateFlags & ESdlThreadExplicitStop);
+ }
+
+void CDsa::SetOrientation(CSDL::TOrientationMode aOrientation)
+ {
+ TInt flags = 0;
+ switch(aOrientation)
+ {
+ case CSDL::EOrientation90:
+ flags = EOrientation90;
+ break;
+ case CSDL::EOrientation180:
+ flags = EOrientation180;
+ break;
+ case CSDL::EOrientation270:
+ flags = EOrientation90 | EOrientation180;
+ break;
+ case CSDL::EOrientation0:
+ flags = 0;
+ break;
+ }
+ if(flags != (iStateFlags & EOrientationFlags))
+ {
+ iStateFlags |= EOrientationChanged;
+ iNewFlags = flags; //cannot be set during drawing...
+ }
+ }
+
+CDsa::~CDsa()
+ {
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ }
+ delete iDsa;
+ User::Free(iLut256);
+ }
+
+void CDsa::ConstructL(RWindow& aWindow, CWsScreenDevice& aDevice)
+ {
+ if(iDsa != NULL)
+ {
+ iDsa->Cancel();
+ delete iDsa;
+ iDsa = NULL;
+ }
+
+
+ iDsa = CDirectScreenAccess::NewL(
+ iSession,
+ aDevice,
+ aWindow,
+ *this);
+
+ if(iLut256 == NULL)
+ iLut256 = (TUint32*) User::AllocL(256 * sizeof(TUint32));
+ iTargetMode = aWindow.DisplayMode();
+ iTargetBpp = BytesPerPixel(DisplayMode());
+ iTargetRect = TRect(aWindow.Position(), aWindow.Size());
+ RestartL();
+ }
+
+void CDsa::LockPalette(TBool aLock)
+ {
+ if(aLock)
+ iStateFlags |= EPaletteLocked;
+ else
+ iStateFlags &= ~EPaletteLocked;
+ }
+TInt CDsa::SetPalette(TInt aFirst, TInt aCount, TUint32* aPalette)
+ {
+ if(iLut256 == NULL)
+ return KErrNotFound;
+ const TInt count = aCount - aFirst;
+ if(count > 256)
+ return KErrArgument;
+ if(iStateFlags & EPaletteLocked)
+ return KErrNone;
+ for(TInt i = aFirst; i < count; i++) //not so busy here:-)
+ {
+ iLut256[i] = aPalette[i];
+ }
+ return KErrNone;
+ }
+
+
+
+
+void CDsa::RestartL()
+ {
+ //const TBool active = iDsa->IsActive();
+
+ //if(!active)
+ iDsa->StartL();
+
+ RRegion* r = iDsa->DrawingRegion();
+ iDsa->Gc()->SetClippingRegion(r);
+ TRect rect = r->BoundingRect();
+
+ if(rect.IsEmpty())
+ {
+ return;
+ }
+
+ iScreenRect = rect; //to ensure properly set, albeit may not(?) match to value SDL has - therefore may has to clip
+
+ RecreateL();
+
+ iStateFlags |= ERunning;
+// iScanLineWidth = iTargetBpp * HwRect().Width();
+ ReleaseStop();
+ if(iStateFlags & ESdlThreadSuspend)
+ {
+ EpocSdlEnv::Resume();
+ iStateFlags &= ~ ESdlThreadSuspend;
+ }
+ }
+
+CDsa::CDsa(RWsSession& aSession) :
+ iSession(aSession),
+ iStateFlags(0)
+ {
+// CActiveScheduler::Add(this);
+ iCFTable[0] = CopyMem;
+ iCFTable[1] = CopyMemFlipReversed;
+ iCFTable[2] = CopyMemReversed;
+ iCFTable[3] = CopyMemFlip;
+
+ iCFTable[4] = Copy256;
+ iCFTable[5] = Copy256FlipReversed;
+ iCFTable[6] = Copy256Reversed;
+ iCFTable[7] = Copy256Flip;
+
+
+ iCFTable[8] = CopySlow;
+ iCFTable[9] = CopySlowFlipReversed;
+ iCFTable[10] = CopySlowReversed;
+ iCFTable[11] = CopySlowFlip;
+ }
+
+RWsSession& CDsa::Session()
+ {
+ return iSession;
+ }
+
+
+
+TUint8* CDsa::LockHwSurface()
+ {
+ if((iStateFlags & EUpdating) == 0) //else frame is skipped
+ {
+ return LockSurface();
+ }
+ return NULL;
+ }
+
+/*
+void CDsa::RunL()
+ {
+ iStateFlags &= ~EUpdating;
+ }
+
+
+void CDsa::DoCancel()
+ {
+ iStateFlags &= ~EUpdating;
+ //nothing can do, just wait?
+ }
+*/
+
+TInt CDsa::AllocSurface(TBool aHwSurface, const TSize& aSize, TDisplayMode aMode)
+ {
+ if(aHwSurface && aMode != DisplayMode())
+ return KErrArgument;
+
+ iSourceMode = aMode;
+
+ iSourceBpp = BytesPerPixel(aMode);
+
+ const TSize size = WindowSize();
+ if(aSize.iWidth > size.iWidth)
+ return KErrTooBig;
+ if(aSize.iHeight > size.iHeight)
+ return KErrTooBig;
+
+ TRAPD(err, CreateSurfaceL());
+ if(err != KErrNone)
+ return err;
+
+
+ SetCopyFunction();
+
+ EpocSdlEnv::ObserverEvent(MSDLObserver::EEventWindowReserved);
+
+ return KErrNone;
+ }
+
+
+/*
+void SaveBmp(const TDesC& aName, const TAny* aData, TInt aLength, const TSize& aSz, TDisplayMode aMode)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, aMode);
+ s->LockHeap();
+ TUint32* addr = s->DataAddress();
+ Mem::Copy(addr, aData, aLength);
+ s->UnlockHeap();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+void SaveBmp(const TDesC& aName, const TUint32* aData, const TSize& aSz)
+ {
+ CFbsBitmap* s = new CFbsBitmap();
+ s->Create(aSz, EColor64K);
+ TBitmapUtil bmp(s);
+ bmp.Begin(TPoint(0, 0));
+ for(TInt j = 0; j < aSz.iHeight; j++)
+ {
+ bmp.SetPos(TPoint(0, j));
+ for(TInt i = 0; i < aSz.iWidth; i++)
+ {
+ bmp.SetPixel(*aData);
+ aData++;
+ bmp.IncXPos();
+ }
+ }
+ bmp.End();
+ s->Save(aName);
+ s->Reset();
+ delete s;
+ }
+
+TBuf<16> FooName(TInt aFoo)
+ {
+ TBuf<16> b;
+ b.Format(_L("C:\\pic%d.mbm"), aFoo);
+ return b;
+ }
+*/
+void CDsa::ClipCopy(TUint8* aTarget, const TUint8* aSource, const TRect& aRect, const TRect& aTargetPos) const
+ {
+ TUint8* target = aTarget;
+ const TUint8* source = aSource;
+ const TInt lineWidth = aRect.Width();
+ source += iSourceBpp * (aRect.iTl.iY * lineWidth);
+ TInt sourceStartOffset = iSourceBpp * aRect.iTl.iX;
+ source += sourceStartOffset;
+ target += iTargetBpp * ((aTargetPos.iTl.iY + aRect.iTl.iY ) * lineWidth);
+ TInt targetStartOffset = iTargetBpp * (aRect.iTl.iX + aTargetPos.iTl.iX);
+ target += targetStartOffset;
+ TUint32* targetPtr = reinterpret_cast<TUint32*>(target);
+ const TInt targetWidth = HwRect().Size().iWidth;
+ const TInt height = aRect.Height();
+
+ TInt lineMove = iStateFlags & EOrientation90 ? 1 : lineWidth;
+
+ if(iStateFlags & EOrientation180)
+ {
+
+ targetPtr += targetWidth * (height - 1);
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, source, lineWidth, height);
+ source += lineMove;
+ targetPtr -= targetWidth;
+ }
+ }
+ else
+ {
+
+
+ for(TInt i = 0; i < height; i++) //source is always smaller
+ {
+ iCopyFunction(*this, targetPtr, source, lineWidth, height);
+ source += lineMove;
+ targetPtr += targetWidth;
+ }
+ }
+
+ }
+
+
+
+
+void CDsa::Wipe() //dont call in drawing
+ {
+ if(IsDsaAvailable())
+ Wipe(iTargetBpp * iScreenRect.Width() * iScreenRect.Height());
+ }
+
+void CDsa::SetCopyFunction()
+ {
+ //calculate offset to correct function in iCFTable according to given parameters
+ TInt function = 0;
+ const TInt KCopyFunctions = 4;
+ const TInt KOffsetToNative = 0;
+ const TInt KOffsetTo256 = KOffsetToNative + KCopyFunctions;
+ const TInt KOffsetToOtherModes = KOffsetTo256 + KCopyFunctions;
+ const TInt KOffsetTo90Functions = 1;
+ const TInt KOffsetTo180Functions = 2;
+
+ if(iSourceMode == DisplayMode())
+ function = KOffsetToNative; //0
+ else if(iSourceMode == EColor256)
+ function = KOffsetTo256; //4
+ else
+ function = KOffsetToOtherModes; //8
+
+ if(iStateFlags & EOrientation90)
+ function += KOffsetTo90Functions; // + 1
+ if(iStateFlags & EOrientation180)
+ function += KOffsetTo180Functions; //+ 2
+
+ iCopyFunction = iCFTable[function];
+
+ Wipe();
+ }
+
+inline void Rotate(TRect& aRect)
+ {
+ const TInt dx = aRect.iBr.iX - aRect.iTl.iX;
+ const TInt dy = aRect.iBr.iY - aRect.iTl.iY;
+
+ aRect.iBr.iX = aRect.iTl.iX + dy;
+ aRect.iBr.iY = aRect.iTl.iY + dx;
+
+ const TInt tmp = aRect.iTl.iX;
+ aRect.iTl.iX = aRect.iTl.iY;
+ aRect.iTl.iY = tmp;
+ }
+
+/*
+int bar = 0;
+*/
+TBool CDsa::AddUpdateRect(const TUint8* aBits, const TRect& aUpdateRect, const TRect& aRect)
+ {
+
+ if(iStateFlags & EOrientationChanged)
+ {
+ iStateFlags &= ~EOrientationFlags;
+ iStateFlags |= iNewFlags;
+ SetCopyFunction();
+ iStateFlags &= ~EOrientationChanged;
+ EpocSdlEnv::WaitDeviceChange();
+ return EFalse; //skip this frame as data is may be changed
+ }
+
+ if(iTargetAddr == NULL)
+ {
+ iTargetAddr = LockHwSurface();
+ }
+ TUint8* target = iTargetAddr;
+ if(target == NULL)
+ return EFalse;
+
+
+ TRect targetRect = HwRect();
+ TRect sourceRect = aRect;
+ TRect updateRect = aUpdateRect;
+
+ if(iStateFlags & EOrientation90)
+ {
+ Rotate(sourceRect);
+ Rotate(updateRect);
+ }
+
+ if(iSourceMode != DisplayMode() || targetRect != sourceRect || targetRect != updateRect || ((iStateFlags & EOrientationFlags) != 0))
+ {
+ sourceRect.Intersection(targetRect); //so source always smaller or equal than target
+ updateRect.Intersection(targetRect);
+ ClipCopy(target, aBits, updateRect, sourceRect);
+ }
+ else
+ {
+ const TInt byteCount = aRect.Width() * aRect.Height() * iSourceBpp; //this could be stored
+ Mem::Copy(target, aBits, byteCount);
+ }
+
+ return ETrue;
+ }
+
+CDsa* CDsa::CreateL(RWsSession& aSession)
+ {
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSB))
+ {
+ TInt flags = CDirectScreenBitmap::ENone;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBDoubleBuffer))
+ flags |= CDirectScreenBitmap::EDoubleBuffer;
+ if(EpocSdlEnv::Flags(CSDL::EDrawModeDSBIncrentalUpdate))
+ flags |= CDirectScreenBitmap::EIncrementalUpdate;
+ return new (ELeave) CDsaB(aSession);
+ }
+ else
+ return new (ELeave) CDsaA(aSession);
+ }
+
+void CDsa::CreateZoomerL(const TSize& aSize)
+ {
+ iSwSize = aSize;
+ iStateFlags |= EResizeRequest;
+ CreateSurfaceL();
+ SetTargetRect();
+ }
+
+TPoint CDsa::WindowCoordinates(const TPoint& aPoint) const
+ {
+ TPoint pos = aPoint - iScreenRect.iTl;
+ const TSize asz = iScreenRect.Size();
+ if(iStateFlags & EOrientation180)
+ {
+ pos.iX = asz.iWidth - pos.iX;
+ pos.iY = asz.iHeight - pos.iY;
+ }
+ if(iStateFlags & EOrientation90)
+ {
+ pos.iX = aPoint.iY;
+ pos.iY = aPoint.iX;
+ }
+ pos.iX <<= 16;
+ pos.iY <<= 16;
+ pos.iX /= asz.iWidth;
+ pos.iY /= asz.iHeight;
+ pos.iX *= iSwSize.iWidth;
+ pos.iY *= iSwSize.iHeight;
+ pos.iX >>= 16;
+ pos.iY >>= 16;
+ return pos;
+ }
+
+void CDsa::SetTargetRect()
+ {
+ iTargetRect = iScreenRect;
+ if(iStateFlags & EResizeRequest && EpocSdlEnv::Flags(CSDL::EAllowImageResizeKeepRatio))
+ {
+ const TSize asz = iScreenRect.Size();
+ const TSize sz = iSwSize;
+
+ TRect rect;
+
+ const TInt dh = (sz.iHeight << 16) / sz.iWidth;
+
+ if((asz.iWidth * dh ) >> 16 <= asz.iHeight)
+ {
+ rect.SetRect(TPoint(0, 0), TSize(asz.iWidth, (asz.iWidth * dh) >> 16));
+ }
+ else
+ {
+ const TInt dw = (sz.iWidth << 16) / sz.iHeight;
+ rect.SetRect(TPoint(0, 0), TSize((asz.iHeight * dw) >> 16, asz.iHeight));
+ }
+ rect.Move((asz.iWidth - rect.Size().iWidth) >> 1, (asz.iHeight - rect.Size().iHeight) >> 1);
+
+ iTargetRect = rect;
+ iTargetRect.Move(iScreenRect.iTl);
+
+ }
+ if(!(iStateFlags & EResizeRequest))
+ iSwSize = iScreenRect.Size();
+// iScanLineWidth = /*iTargetBpp **/ SwSize().iWidth;
+ }
+
+void CDsa::RecreateL()
+ {
+ }
+
+void CDsa::Free()
+ {
+ }
+
+void CDsa::UpdateSwSurface()
+ {
+ iTargetAddr = NULL;
+ UnlockHwSurface(); //could be faster if does not use AO, but only check status before redraw, then no context switch needed
+ }
+
+void CDsa::SetBlitter(MBlitter* aBlitter)
+ {
+ iBlitter = aBlitter;
+ }
+
+void CDsa::DrawOverlays()
+ {
+ const TInt last = iOverlays.Count() - 1;
+ for(TInt i = last; i >= 0 ; i--)
+ iOverlays[i].iOverlay->Draw(*iDsa->Gc(), HwRect(), SwSize());
+ }
+
+TInt CDsa::AppendOverlay(MOverlay& aOverlay, TInt aPriority)
+ {
+ TInt i;
+ for(i = 0; i < iOverlays.Count() && iOverlays[i].iPriority < aPriority; i++)
+ {}
+ const TOverlay overlay = {&aOverlay, aPriority};
+ return iOverlays.Insert(overlay, i);
+ }
+
+TInt CDsa::RemoveOverlay(MOverlay& aOverlay)
+ {
+ for(TInt i = 0; i < iOverlays.Count(); i++)
+ {
+ if(iOverlays[i].iOverlay == &aOverlay)
+ {
+ iOverlays.Remove(i);
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+TInt CDsa::RedrawRequest()
+ {
+ if(!(iStateFlags & (EUpdating) && (iStateFlags & ERunning)))
+ {
+ return ExternalUpdate();
+ }
+ return KErrNotReady;
+ }
+
+
+void CDsa::Resume()
+ {
+ if(Stopped())
+ Restart(RDirectScreenAccess::ETerminateRegion);
+ }
+
+void CDsa::DoStop()
+ {
+ if(IsDsaAvailable())
+ iStateFlags |= ESdlThreadExplicitStop;
+ Stop();
+ }
+
+void CDsa::Stop()
+ {
+ iStateFlags &= ~ERunning;
+// Cancel(); //can be called only from main!
+ iDsa->Cancel();
+ }
+
+void CDsa::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
+ {
+// iStateFlags |= EChangeNotify;
+ Stop();
+ }
+
+void CDsa::Restart(RDirectScreenAccess::TTerminationReasons aReason)
+ {
+ if(aReason == RDirectScreenAccess::ETerminateRegion) //auto restart
+ {
+ TRAPD(err, RestartL());
+ PANIC_IF_ERROR(err);
+ }
+ }
+/*)
+TBool CDsa::ChangeTrigger()
+ {
+ const TBool change = iStateFlags & EChangeNotify;
+ iStateFlags &= ~EChangeNotify;
+ return change;
+ }
+*/
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CDsa::Copy256(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Reversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* source = aSource;
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*source++];
+ }
+ }
+
+void CDsa::Copy256Flip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *target++ = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::Copy256FlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint8* column = aSource;
+
+ while(target < endt)
+ {
+ *(--endt) = aDsa.iLut256[*column];
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMem(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ Mem::Copy(aTarget, aSource, aBytes);
+ }
+
+void CDsa::CopyMemFlip(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TUint32* target = aTarget;
+ const TUint32* endt = target + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *target++ = *column;
+ column += aLineLen;
+ }
+ }
+
+void CDsa::CopyMemReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* source = reinterpret_cast<const TUint32*>(aSource);
+ while(target < endt)
+ {
+ *(--endt) = *source++;
+ }
+ }
+
+
+void CDsa::CopyMemFlipReversed(const CDsa& /*aDsa*/, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ const TUint32* target = aTarget;
+ TUint32* endt = aTarget + aBytes;
+ const TUint32* column = reinterpret_cast<const TUint32*>(aSource);
+
+ while(target < endt)
+ {
+ *(--endt) = *column;
+ column += aLineLen;
+ }
+ }
+
+
+typedef TRgb (*TRgbFunc) (TInt aValue);
+
+LOCAL_C TRgb rgb16MA(TInt aValue)
+ {
+ return TRgb::Color16MA(aValue);
+ }
+
+NONSHARABLE_CLASS(MRgbCopy)
+ {
+ public:
+ virtual void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed) = 0;
+ virtual void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed) = 0;
+ };
+template <class T>
+NONSHARABLE_CLASS(TRgbCopy) : public MRgbCopy
+ {
+ public:
+ TRgbCopy(TDisplayMode aMode);
+ void* operator new(TUint aBytes, TAny* aMem);
+ void Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed);
+ void FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed);
+ private:
+ TRgbFunc iFunc;
+ };
+
+template <class T>
+void* TRgbCopy<T>::operator new(TUint /*aBytes*/, TAny* aMem)
+ {
+ return aMem;
+ }
+
+template <class T>
+TRgbCopy<T>::TRgbCopy(TDisplayMode aMode)
+ {
+ switch(aMode)
+ {
+ case EGray256 : iFunc = TRgb::Gray256; break;
+ case EColor256 : iFunc = TRgb::Color256; break;
+ case EColor4K : iFunc = TRgb::Color4K; break;
+ case EColor64K : iFunc = TRgb::Color64K; break;
+ case EColor16M : iFunc = TRgb::Color16M; break;
+ case EColor16MU : iFunc = TRgb::Color16MU; break;
+ case EColor16MA : iFunc = rgb16MA; break;
+ default:
+ PANIC(KErrNotSupported);
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::Copy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TBool aReversed)
+ {
+ const T* source = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ TUint32 value = *source++;
+ *(--endt) = iFunc(value).Value();
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ TUint32 value = *source++;
+ *target++ = iFunc(value).Value();
+ }
+ }
+ }
+
+template <class T>
+void TRgbCopy<T>::FlipCopy(TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen, TBool aReversed)
+ {
+ const T* column = reinterpret_cast<const T*>(aSource);
+ TUint32* target = aTarget;
+ TUint32* endt = target + aBytes;
+
+ if(aReversed)
+ {
+ while(target < endt)
+ {
+ *(--endt) = iFunc(*column).Value();
+ column += aLineLen;
+ }
+ }
+ else
+ {
+ while(target < endt)
+ {
+ *target++ = iFunc(*column).Value();
+ column += aLineLen;
+ }
+ }
+ }
+
+
+typedef TUint64 TStackMem;
+
+LOCAL_C MRgbCopy* GetCopy(TAny* mem, TDisplayMode aMode)
+ {
+ if(aMode == EColor256 || aMode == EGray256)
+ {
+ return new (mem) TRgbCopy<TUint8>(aMode);
+ }
+ if(aMode == EColor4K || aMode == EColor64K)
+ {
+ return new (mem) TRgbCopy<TUint16>(aMode);
+ }
+ if(aMode == EColor16M || aMode == EColor16MU || aMode == EColor16MA)
+ {
+ return new (mem) TRgbCopy<TUint32>(aMode);
+ }
+ PANIC(KErrNotSupported);
+ return NULL;
+ }
+
+
+void CDsa::CopySlowFlipReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, ETrue);
+ }
+
+void CDsa::CopySlowFlip(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt aLineLen)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->FlipCopy(aTarget, aSource, aBytes, aLineLen, EFalse);
+ }
+
+void CDsa::CopySlow(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, EFalse);
+ }
+
+void CDsa::CopySlowReversed(const CDsa& aDsa, TUint32* aTarget, const TUint8* aSource, TInt aBytes, TInt)
+ {
+ TStackMem mem = 0;
+ GetCopy(&mem, aDsa.iSourceMode)->Copy(aTarget, aSource, aBytes, ETrue);
+ } \ No newline at end of file
diff --git a/distrib/sdl-1.2.15/src/video/symbian/SDL_epocevents_c.h b/distrib/sdl-1.2.15/src/video/symbian/SDL_epocevents_c.h
new file mode 100644
index 0000000..8e10a04
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/symbian/SDL_epocevents_c.h
@@ -0,0 +1,60 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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@devolution.com
+*/
+
+/*
+ SDL_epocevents_c.h
+ Handle the event stream, converting Epoc events into SDL events
+
+ Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) and Markus Mertama
+
+*/
+
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: SDL_aaevents_c.h,v 1.1.2.2 2000/03/16 15:20:39 hercules Exp $";
+#endif
+
+extern "C" {
+#include "SDL_sysvideo.h"
+//#include "SDL_epocvideo.h"
+}
+
+
+
+#define MAX_SCANCODE 255
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *_this
+#define Private _this->hidden
+
+extern "C" {
+extern void EPOC_InitOSKeymap(_THIS);
+extern void EPOC_PumpEvents(_THIS);
+}
+
+extern TBool isCursorVisible;
+
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents.c b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents.c
new file mode 100644
index 0000000..fa6c9e7
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents.c
@@ -0,0 +1,299 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting X11 events into SDL events */
+
+#include <stdio.h>
+
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/kbio.h>
+#include <vgl.h>
+
+#include "SDL.h"
+#include "SDL_thread.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_vglvideo.h"
+#include "SDL_vglevents_c.h"
+
+/* The translation tables from a console scancode to a SDL keysym */
+/* FIXME: Free the keymap when we shut down the video mode */
+static keymap_t *vga_keymap = NULL;
+static SDLKey keymap[128];
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
+
+static int posted = 0;
+static int oldx = -1;
+static int oldy = -1;
+static struct mouse_info mouseinfo;
+
+/* Ugh, we have to duplicate the kernel's keysym mapping code...
+ Oh, it's not so bad. :-)
+
+ FIXME: Add keyboard LED handling code
+ */
+int VGL_initkeymaps(int fd)
+{
+ vga_keymap = SDL_malloc(sizeof(keymap_t));
+ if ( ! vga_keymap ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ if (ioctl(fd, GIO_KEYMAP, vga_keymap) == -1) {
+ SDL_free(vga_keymap);
+ vga_keymap = NULL;
+ SDL_SetError("Unable to get keyboard map");
+ return(-1);
+ }
+ return(0);
+}
+
+static void handle_keyboard(_THIS)
+{
+ SDL_keysym keysym;
+ int c, pressed, scancode;
+
+ while ((c = VGLKeyboardGetCh()) != 0) {
+ scancode = c & 0x7F;
+ if (c & 0x80) {
+ pressed = SDL_RELEASED;
+ } else {
+ pressed = SDL_PRESSED;
+ }
+
+ posted += SDL_PrivateKeyboard(pressed,
+ TranslateKey(scancode, &keysym));
+ }
+}
+
+int VGL_initmouse(int fd)
+{
+ mouseinfo.operation = MOUSE_GETINFO;
+ if (ioctl(fd, CONS_MOUSECTL, &mouseinfo) != 0)
+ return -1;
+
+ return 0;
+}
+
+static void handle_mouse(_THIS)
+{
+ char buttons;
+ int x, y;
+ int button_state, state_changed, state;
+ int i;
+
+ ioctl(0, CONS_MOUSECTL, &mouseinfo);
+ x = mouseinfo.u.data.x;
+ y = mouseinfo.u.data.y;
+ buttons = mouseinfo.u.data.buttons;
+
+ if ((x != oldx) || (y != oldy)) {
+ posted += SDL_PrivateMouseMotion(0, 0, x, y);
+ oldx = x;
+ oldy = y;
+ }
+
+ /* See what's changed */
+ button_state = SDL_GetMouseState(NULL, NULL);
+ state_changed = button_state ^ buttons;
+ for (i = 0; i < 8; i++) {
+ if (state_changed & (1<<i)) {
+ if (buttons & (1<<i)) {
+ state = SDL_PRESSED;
+ } else {
+ state = SDL_RELEASED;
+ }
+ posted += SDL_PrivateMouseButton(state, i + 1, 0, 0);
+ }
+ }
+}
+
+
+void VGL_PumpEvents(_THIS)
+{
+ do {
+ posted = 0;
+ handle_keyboard(this);
+ handle_mouse(this);
+ } while (posted != 0);
+}
+
+void VGL_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Initialize the BeOS key translation table */
+ for ( i=0; i<SDL_arraysize(keymap); ++i )
+ keymap[i] = SDLK_UNKNOWN;
+
+ keymap[SCANCODE_ESCAPE] = SDLK_ESCAPE;
+ keymap[SCANCODE_1] = SDLK_1;
+ keymap[SCANCODE_2] = SDLK_2;
+ keymap[SCANCODE_3] = SDLK_3;
+ keymap[SCANCODE_4] = SDLK_4;
+ keymap[SCANCODE_5] = SDLK_5;
+ keymap[SCANCODE_6] = SDLK_6;
+ keymap[SCANCODE_7] = SDLK_7;
+ keymap[SCANCODE_8] = SDLK_8;
+ keymap[SCANCODE_9] = SDLK_9;
+ keymap[SCANCODE_0] = SDLK_0;
+ keymap[SCANCODE_MINUS] = SDLK_MINUS;
+ keymap[SCANCODE_EQUAL] = SDLK_EQUALS;
+ keymap[SCANCODE_BACKSPACE] = SDLK_BACKSPACE;
+ keymap[SCANCODE_TAB] = SDLK_TAB;
+ keymap[SCANCODE_Q] = SDLK_q;
+ keymap[SCANCODE_W] = SDLK_w;
+ keymap[SCANCODE_E] = SDLK_e;
+ keymap[SCANCODE_R] = SDLK_r;
+ keymap[SCANCODE_T] = SDLK_t;
+ keymap[SCANCODE_Y] = SDLK_y;
+ keymap[SCANCODE_U] = SDLK_u;
+ keymap[SCANCODE_I] = SDLK_i;
+ keymap[SCANCODE_O] = SDLK_o;
+ keymap[SCANCODE_P] = SDLK_p;
+ keymap[SCANCODE_BRACKET_LEFT] = SDLK_LEFTBRACKET;
+ keymap[SCANCODE_BRACKET_RIGHT] = SDLK_RIGHTBRACKET;
+ keymap[SCANCODE_ENTER] = SDLK_RETURN;
+ keymap[SCANCODE_LEFTCONTROL] = SDLK_LCTRL;
+ keymap[SCANCODE_A] = SDLK_a;
+ keymap[SCANCODE_S] = SDLK_s;
+ keymap[SCANCODE_D] = SDLK_d;
+ keymap[SCANCODE_F] = SDLK_f;
+ keymap[SCANCODE_G] = SDLK_g;
+ keymap[SCANCODE_H] = SDLK_h;
+ keymap[SCANCODE_J] = SDLK_j;
+ keymap[SCANCODE_K] = SDLK_k;
+ keymap[SCANCODE_L] = SDLK_l;
+ keymap[SCANCODE_SEMICOLON] = SDLK_SEMICOLON;
+ keymap[SCANCODE_APOSTROPHE] = SDLK_QUOTE;
+ keymap[SCANCODE_GRAVE] = SDLK_BACKQUOTE;
+ keymap[SCANCODE_LEFTSHIFT] = SDLK_LSHIFT;
+ keymap[SCANCODE_BACKSLASH] = SDLK_BACKSLASH;
+ keymap[SCANCODE_Z] = SDLK_z;
+ keymap[SCANCODE_X] = SDLK_x;
+ keymap[SCANCODE_C] = SDLK_c;
+ keymap[SCANCODE_V] = SDLK_v;
+ keymap[SCANCODE_B] = SDLK_b;
+ keymap[SCANCODE_N] = SDLK_n;
+ keymap[SCANCODE_M] = SDLK_m;
+ keymap[SCANCODE_COMMA] = SDLK_COMMA;
+ keymap[SCANCODE_PERIOD] = SDLK_PERIOD;
+ keymap[SCANCODE_SLASH] = SDLK_SLASH;
+ keymap[SCANCODE_RIGHTSHIFT] = SDLK_RSHIFT;
+ keymap[SCANCODE_KEYPADMULTIPLY] = SDLK_KP_MULTIPLY;
+ keymap[SCANCODE_LEFTALT] = SDLK_LALT;
+ keymap[SCANCODE_SPACE] = SDLK_SPACE;
+ keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK;
+ keymap[SCANCODE_F1] = SDLK_F1;
+ keymap[SCANCODE_F2] = SDLK_F2;
+ keymap[SCANCODE_F3] = SDLK_F3;
+ keymap[SCANCODE_F4] = SDLK_F4;
+ keymap[SCANCODE_F5] = SDLK_F5;
+ keymap[SCANCODE_F6] = SDLK_F6;
+ keymap[SCANCODE_F7] = SDLK_F7;
+ keymap[SCANCODE_F8] = SDLK_F8;
+ keymap[SCANCODE_F9] = SDLK_F9;
+ keymap[SCANCODE_F10] = SDLK_F10;
+ keymap[SCANCODE_NUMLOCK] = SDLK_NUMLOCK;
+ keymap[SCANCODE_SCROLLLOCK] = SDLK_SCROLLOCK;
+ keymap[SCANCODE_KEYPAD7] = SDLK_KP7;
+ keymap[SCANCODE_CURSORUPLEFT] = SDLK_KP7;
+ keymap[SCANCODE_KEYPAD8] = SDLK_KP8;
+ keymap[SCANCODE_CURSORUP] = SDLK_KP8;
+ keymap[SCANCODE_KEYPAD9] = SDLK_KP9;
+ keymap[SCANCODE_CURSORUPRIGHT] = SDLK_KP9;
+ keymap[SCANCODE_KEYPADMINUS] = SDLK_KP_MINUS;
+ keymap[SCANCODE_KEYPAD4] = SDLK_KP4;
+ keymap[SCANCODE_CURSORLEFT] = SDLK_KP4;
+ keymap[SCANCODE_KEYPAD5] = SDLK_KP5;
+ keymap[SCANCODE_KEYPAD6] = SDLK_KP6;
+ keymap[SCANCODE_CURSORRIGHT] = SDLK_KP6;
+ keymap[SCANCODE_KEYPADPLUS] = SDLK_KP_PLUS;
+ keymap[SCANCODE_KEYPAD1] = SDLK_KP1;
+ keymap[SCANCODE_CURSORDOWNLEFT] = SDLK_KP1;
+ keymap[SCANCODE_KEYPAD2] = SDLK_KP2;
+ keymap[SCANCODE_CURSORDOWN] = SDLK_KP2;
+ keymap[SCANCODE_KEYPAD3] = SDLK_KP3;
+ keymap[SCANCODE_CURSORDOWNRIGHT] = SDLK_KP3;
+ keymap[SCANCODE_KEYPAD0] = SDLK_KP0;
+ keymap[SCANCODE_KEYPADPERIOD] = SDLK_KP_PERIOD;
+ keymap[SCANCODE_LESS] = SDLK_LESS;
+ keymap[SCANCODE_F11] = SDLK_F11;
+ keymap[SCANCODE_F12] = SDLK_F12;
+ keymap[SCANCODE_KEYPADENTER] = SDLK_KP_ENTER;
+ keymap[SCANCODE_RIGHTCONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_CONTROL] = SDLK_RCTRL;
+ keymap[SCANCODE_KEYPADDIVIDE] = SDLK_KP_DIVIDE;
+ keymap[SCANCODE_PRINTSCREEN] = SDLK_PRINT;
+ keymap[SCANCODE_RIGHTALT] = SDLK_RALT;
+ keymap[SCANCODE_BREAK] = SDLK_BREAK;
+ keymap[SCANCODE_BREAK_ALTERNATIVE] = SDLK_UNKNOWN;
+ keymap[SCANCODE_HOME] = SDLK_HOME;
+ keymap[SCANCODE_CURSORBLOCKUP] = SDLK_UP;
+ keymap[SCANCODE_PAGEUP] = SDLK_PAGEUP;
+ keymap[SCANCODE_CURSORBLOCKLEFT] = SDLK_LEFT;
+ keymap[SCANCODE_CURSORBLOCKRIGHT] = SDLK_RIGHT;
+ keymap[SCANCODE_END] = SDLK_END;
+ keymap[SCANCODE_CURSORBLOCKDOWN] = SDLK_DOWN;
+ keymap[SCANCODE_PAGEDOWN] = SDLK_PAGEDOWN;
+ keymap[SCANCODE_INSERT] = SDLK_INSERT;
+ keymap[SCANCODE_REMOVE] = SDLK_DELETE;
+ keymap[119] = SDLK_PAUSE;
+ keymap[SCANCODE_RIGHTWIN] = SDLK_RSUPER;
+ keymap[SCANCODE_LEFTWIN] = SDLK_LSUPER;
+ keymap[127] = SDLK_MENU;
+}
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ /* Set the keysym information */
+ keysym->scancode = scancode;
+ keysym->sym = keymap[scancode];
+ keysym->mod = KMOD_NONE;
+
+ /* If UNICODE is on, get the UNICODE value for the key */
+ keysym->unicode = 0;
+ if ( SDL_TranslateUNICODE && vga_keymap ) {
+ int map;
+ SDLMod modstate;
+
+ modstate = SDL_GetModState();
+ map = 0;
+ if ( modstate & KMOD_SHIFT ) {
+ map += 1;
+ }
+ if ( modstate & KMOD_CTRL ) {
+ map += 2;
+ }
+ if ( modstate & KMOD_ALT ) {
+ map += 4;
+ }
+ if ( !(vga_keymap->key[scancode].spcl & (0x80 >> map)) ) {
+ keysym->unicode = vga_keymap->key[scancode].map[map];
+ }
+
+ }
+ return(keysym);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents_c.h b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents_c.h
new file mode 100644
index 0000000..614cab5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglevents_c.h
@@ -0,0 +1,155 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_vglvideo.h"
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern int VGL_initkeymaps(int fd);
+extern int VGL_initmouse(int fd);
+extern void VGL_keyboardcallback(int scancode, int pressed);
+
+extern void VGL_InitOSKeymap(_THIS);
+extern void VGL_PumpEvents(_THIS);
+
+/* Mouse buttons */
+#define MOUSE_LEFTBUTTON 0x01
+#define MOUSE_MIDDLEBUTTON 0x02
+#define MOUSE_RIGHTBUTTON 0x04
+
+/* Scancodes */
+#define SCANCODE_ESCAPE 1
+#define SCANCODE_1 2
+#define SCANCODE_2 3
+#define SCANCODE_3 4
+#define SCANCODE_4 5
+#define SCANCODE_5 6
+#define SCANCODE_6 7
+#define SCANCODE_7 8
+#define SCANCODE_8 9
+#define SCANCODE_9 10
+#define SCANCODE_0 11
+#define SCANCODE_MINUS 12
+#define SCANCODE_EQUAL 13
+#define SCANCODE_BACKSPACE 14
+#define SCANCODE_TAB 15
+#define SCANCODE_Q 16
+#define SCANCODE_W 17
+#define SCANCODE_E 18
+#define SCANCODE_R 19
+#define SCANCODE_T 20
+#define SCANCODE_Y 21
+#define SCANCODE_U 22
+#define SCANCODE_I 23
+#define SCANCODE_O 24
+#define SCANCODE_P 25
+#define SCANCODE_BRACKET_LEFT 26
+#define SCANCODE_BRACKET_RIGHT 27
+#define SCANCODE_ENTER 28
+#define SCANCODE_LEFTCONTROL 29
+#define SCANCODE_A 30
+#define SCANCODE_S 31
+#define SCANCODE_D 32
+#define SCANCODE_F 33
+#define SCANCODE_G 34
+#define SCANCODE_H 35
+#define SCANCODE_J 36
+#define SCANCODE_K 37
+#define SCANCODE_L 38
+#define SCANCODE_SEMICOLON 39
+#define SCANCODE_APOSTROPHE 40
+#define SCANCODE_GRAVE 41
+#define SCANCODE_LEFTSHIFT 42
+#define SCANCODE_BACKSLASH 43
+#define SCANCODE_Z 44
+#define SCANCODE_X 45
+#define SCANCODE_C 46
+#define SCANCODE_V 47
+#define SCANCODE_B 48
+#define SCANCODE_N 49
+#define SCANCODE_M 50
+#define SCANCODE_COMMA 51
+#define SCANCODE_PERIOD 52
+#define SCANCODE_SLASH 53
+#define SCANCODE_RIGHTSHIFT 54
+#define SCANCODE_KEYPADMULTIPLY 55
+#define SCANCODE_LEFTALT 56
+#define SCANCODE_SPACE 57
+#define SCANCODE_CAPSLOCK 58
+#define SCANCODE_F1 59
+#define SCANCODE_F2 60
+#define SCANCODE_F3 61
+#define SCANCODE_F4 62
+#define SCANCODE_F5 63
+#define SCANCODE_F6 64
+#define SCANCODE_F7 65
+#define SCANCODE_F8 66
+#define SCANCODE_F9 67
+#define SCANCODE_F10 68
+#define SCANCODE_NUMLOCK 69
+#define SCANCODE_SCROLLLOCK 70
+#define SCANCODE_KEYPAD7 71
+#define SCANCODE_CURSORUPLEFT 71
+#define SCANCODE_KEYPAD8 72
+#define SCANCODE_CURSORUP 72
+#define SCANCODE_KEYPAD9 73
+#define SCANCODE_CURSORUPRIGHT 73
+#define SCANCODE_KEYPADMINUS 74
+#define SCANCODE_KEYPAD4 75
+#define SCANCODE_CURSORLEFT 75
+#define SCANCODE_KEYPAD5 76
+#define SCANCODE_KEYPAD6 77
+#define SCANCODE_CURSORRIGHT 77
+#define SCANCODE_KEYPADPLUS 78
+#define SCANCODE_KEYPAD1 79
+#define SCANCODE_CURSORDOWNLEFT 79
+#define SCANCODE_KEYPAD2 80
+#define SCANCODE_CURSORDOWN 80
+#define SCANCODE_KEYPAD3 81
+#define SCANCODE_CURSORDOWNRIGHT 81
+#define SCANCODE_KEYPAD0 82
+#define SCANCODE_KEYPADPERIOD 83
+#define SCANCODE_LESS 86
+#define SCANCODE_F11 87
+#define SCANCODE_F12 88
+#define SCANCODE_KEYPADENTER 89
+#define SCANCODE_RIGHTCONTROL 90
+#define SCANCODE_CONTROL 107
+#define SCANCODE_KEYPADDIVIDE 91
+#define SCANCODE_PRINTSCREEN 92
+#define SCANCODE_RIGHTALT 93
+#define SCANCODE_BREAK 104 /* Beware: is 119 */
+#define SCANCODE_BREAK_ALTERNATIVE 104 /* on some keyboards! */
+#define SCANCODE_HOME 94
+#define SCANCODE_CURSORBLOCKUP 95 /* Cursor key block */
+#define SCANCODE_PAGEUP 96
+#define SCANCODE_CURSORBLOCKLEFT 97 /* Cursor key block */
+#define SCANCODE_CURSORBLOCKRIGHT 98 /* Cursor key block */
+#define SCANCODE_END 99
+#define SCANCODE_CURSORBLOCKDOWN 100 /* Cursor key block */
+#define SCANCODE_PAGEDOWN 101
+#define SCANCODE_INSERT 102
+#define SCANCODE_REMOVE 103
+#define SCANCODE_RIGHTWIN 106
+#define SCANCODE_LEFTWIN 105
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse.c b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse.c
new file mode 100644
index 0000000..466f1c5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse.c
@@ -0,0 +1,56 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_vglvideo.h"
+#include "SDL_vglmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
+
+
+void VGL_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ return;
+}
+
+WMcursor *VGL_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ return(NULL);
+}
+
+int VGL_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ return(0);
+}
+
+void VGL_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse_c.h b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse_c.h
new file mode 100644
index 0000000..f579d65
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglmouse_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_vglvideo.h"
+
+/* Functions to be exported */
+extern void VGL_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *VGL_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int VGL_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void VGL_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.c b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.c
new file mode 100644
index 0000000..0b61615
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.c
@@ -0,0 +1,624 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* libvga based SDL video driver implementation.
+*/
+
+#include <err.h>
+#include <osreldate.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/kbio.h>
+#include <vgl.h>
+
+#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_vglvideo.h"
+#include "SDL_vglevents_c.h"
+#include "SDL_vglmouse_c.h"
+
+
+/* Initialization/Query functions */
+static int VGL_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **VGL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int VGL_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void VGL_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int VGL_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int VGL_LockHWSurface(_THIS, SDL_Surface *surface);
+static int VGL_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void VGL_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void VGL_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Misc function */
+static VGLMode ** VGLListModes(int depth, int mem_model);
+
+/* VGL driver bootstrap functions */
+
+static int VGL_Available(void)
+{
+ /*
+ * Check to see if we are root and stdin is a
+ * virtual console. Also try to ensure that
+ * modes other than 320x200 are available
+ */
+ int console, hires_available, i;
+ VGLMode **modes;
+
+ console = STDIN_FILENO;
+ if ( console >= 0 ) {
+ struct stat sb;
+ struct vt_mode dummy;
+
+ if ( (fstat(console, &sb) < 0) ||
+ (ioctl(console, VT_GETMODE, &dummy) < 0) ) {
+ console = -1;
+ }
+ }
+ if (geteuid() != 0 && console == -1)
+ return 0;
+
+ modes = VGLListModes(8, V_INFO_MM_DIRECT | V_INFO_MM_PACKED);
+ hires_available = 0;
+ for (i = 0; modes[i] != NULL; i++) {
+ if ((modes[i]->ModeInfo.Xsize > 320) &&
+ (modes[i]->ModeInfo.Ysize > 200) &&
+ ((modes[i]->ModeInfo.Type == VIDBUF8) ||
+ (modes[i]->ModeInfo.Type == VIDBUF16) ||
+ (modes[i]->ModeInfo.Type == VIDBUF32))) {
+ hires_available = 1;
+ break;
+ }
+ }
+ return hires_available;
+}
+
+static void VGL_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *VGL_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+
+ /* Set the function pointers */
+ device->VideoInit = VGL_VideoInit;
+ device->ListModes = VGL_ListModes;
+ device->SetVideoMode = VGL_SetVideoMode;
+ device->SetColors = VGL_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = VGL_VideoQuit;
+ device->AllocHWSurface = VGL_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = VGL_LockHWSurface;
+ device->UnlockHWSurface = VGL_UnlockHWSurface;
+ device->FlipHWSurface = VGL_FlipHWSurface;
+ device->FreeHWSurface = VGL_FreeHWSurface;
+ device->SetIcon = NULL;
+ device->SetCaption = NULL;
+ device->GetWMInfo = NULL;
+ device->FreeWMCursor = VGL_FreeWMCursor;
+ device->CreateWMCursor = VGL_CreateWMCursor;
+ device->ShowWMCursor = VGL_ShowWMCursor;
+ device->WarpWMCursor = VGL_WarpWMCursor;
+ device->InitOSKeymap = VGL_InitOSKeymap;
+ device->PumpEvents = VGL_PumpEvents;
+
+ device->free = VGL_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap VGL_bootstrap = {
+ "vgl", "FreeBSD libVGL",
+ VGL_Available, VGL_CreateDevice
+};
+
+static int VGL_AddMode(_THIS, VGLMode *inmode)
+{
+ SDL_Rect *mode;
+
+ int i, index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if (inmode->Depth < 8) { /* Not supported */
+ return 0;
+ }
+ index = ((inmode->Depth + 7) / 8) - 1;
+ for (i=0; i<SDL_nummodes[index]; ++i) {
+ mode = SDL_modelist[index][i];
+ if ((mode->w == inmode->ModeInfo.Xsize) &&
+ (mode->h == inmode->ModeInfo.Ysize))
+ return 0;
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if (mode == NULL) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = inmode->ModeInfo.Xsize;
+ mode->h = inmode->ModeInfo.Ysize;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if (SDL_modelist[index] == NULL) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return -1;
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return 0;
+}
+
+static void VGL_UpdateVideoInfo(_THIS)
+{
+ this->info.wm_available = 0;
+ this->info.hw_available = 1;
+ this->info.video_mem = 0;
+ if (VGLCurMode == NULL) {
+ return;
+ }
+ if (VGLCurMode->ModeInfo.PixelBytes > 0) {
+ this->info.video_mem = VGLCurMode->ModeInfo.PixelBytes *
+ VGLCurMode->ModeInfo.Xsize *
+ VGLCurMode->ModeInfo.Ysize;
+ }
+}
+
+int VGL_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i;
+ int total_modes;
+ VGLMode **modes;
+
+ /* Initialize all variables that we clean on shutdown */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_nummodes[i] = 0;
+ SDL_modelist[i] = NULL;
+ }
+
+ /* Enable mouse and keyboard support */
+ if (SDL_getenv("SDL_NO_RAWKBD") == NULL) {
+ if (VGLKeyboardInit(VGL_CODEKEYS) != 0) {
+ SDL_SetError("Unable to initialize keyboard");
+ return -1;
+ }
+ } else {
+ warnx("Requiest to put keyboard into a raw mode ignored");
+ }
+ if (VGL_initkeymaps(STDIN_FILENO) != 0) {
+ SDL_SetError("Unable to initialize keymap");
+ return -1;
+ }
+ if (VGL_initmouse(STDIN_FILENO) != 0) {
+ SDL_SetError("Unable to initialize mouse");
+ return -1;
+ }
+
+ /* Determine the current screen size */
+ if (VGLCurMode != NULL) {
+ this->info.current_w = VGLCurMode->ModeInfo.Xsize;
+ this->info.current_h = VGLCurMode->ModeInfo.Ysize;
+ }
+
+ /* Determine the screen depth */
+ if (VGLCurMode != NULL)
+ vformat->BitsPerPixel = VGLCurMode->Depth;
+ else
+ vformat->BitsPerPixel = 16; /* Good default */
+
+ /* Query for the list of available video modes */
+ total_modes = 0;
+ modes = VGLListModes(-1, V_INFO_MM_DIRECT | V_INFO_MM_PACKED);
+ for (i = 0; modes[i] != NULL; i++) {
+ if ((modes[i]->ModeInfo.Type == VIDBUF8) ||
+ (modes[i]->ModeInfo.Type == VIDBUF16) ||
+ (modes[i]->ModeInfo.Type == VIDBUF32)) {
+ VGL_AddMode(this, modes[i]);
+ total_modes++;
+ }
+ }
+ if (total_modes == 0) {
+ SDL_SetError("No linear video modes available");
+ return -1;
+ }
+
+ /* Fill in our hardware acceleration capabilities */
+ VGL_UpdateVideoInfo(this);
+
+ /* Create the hardware surface lock mutex */
+ hw_lock = SDL_CreateMutex();
+ if (hw_lock == NULL) {
+ SDL_SetError("Unable to create lock mutex");
+ VGL_VideoQuit(this);
+ return -1;
+ }
+
+ /* We're done! */
+ return 0;
+}
+
+SDL_Rect **VGL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return SDL_modelist[((format->BitsPerPixel+7)/8)-1];
+}
+
+/* Various screen update functions available */
+static void VGL_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ int mode_found;
+ int i;
+ VGLMode **modes;
+
+ modes = VGLListModes(bpp, V_INFO_MM_DIRECT | V_INFO_MM_PACKED);
+ mode_found = 0;
+ for (i = 0; modes[i] != NULL; i++) {
+ if ((modes[i]->ModeInfo.Xsize == width) &&
+ (modes[i]->ModeInfo.Ysize == height) &&
+ ((modes[i]->ModeInfo.Type == VIDBUF8) ||
+ (modes[i]->ModeInfo.Type == VIDBUF16) ||
+ (modes[i]->ModeInfo.Type == VIDBUF32))) {
+ mode_found = 1;
+ break;
+ }
+ }
+ if (mode_found == 0) {
+ SDL_SetError("No matching video mode found");
+ return NULL;
+ }
+
+ /* Shutdown previous videomode (if any) */
+ if (VGLCurMode != NULL)
+ VGLEnd();
+
+ /* Try to set the requested linear video mode */
+ if (VGLInit(modes[i]->ModeId) != 0) {
+ SDL_SetError("Unable to switch to requested mode");
+ return NULL;
+ }
+
+ VGLCurMode = SDL_realloc(VGLCurMode, sizeof(VGLMode));
+ VGLCurMode->ModeInfo = *VGLDisplay;
+ VGLCurMode->Depth = modes[i]->Depth;
+ VGLCurMode->ModeId = modes[i]->ModeId;
+ VGLCurMode->Rmask = modes[i]->Rmask;
+ VGLCurMode->Gmask = modes[i]->Gmask;
+ VGLCurMode->Bmask = modes[i]->Bmask;
+
+ /* Workaround a bug in libvgl */
+ if (VGLCurMode->ModeInfo.PixelBytes == 0)
+ (VGLCurMode->ModeInfo.PixelBytes = 1);
+
+ current->w = VGLCurMode->ModeInfo.Xsize;
+ current->h = VGLCurMode->ModeInfo.Ysize;
+ current->pixels = VGLCurMode->ModeInfo.Bitmap;
+ current->pitch = VGLCurMode->ModeInfo.Xsize *
+ VGLCurMode->ModeInfo.PixelBytes;
+ current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE);
+
+ /* Check if we are in a pseudo-color mode */
+ if (VGLCurMode->ModeInfo.Type == VIDBUF8)
+ current->flags |= SDL_HWPALETTE;
+
+ /* Check if we can do doublebuffering */
+ if (flags & SDL_DOUBLEBUF) {
+ if (VGLCurMode->ModeInfo.Xsize * 2 <=
+ VGLCurMode->ModeInfo.VYsize) {
+ current->flags |= SDL_DOUBLEBUF;
+ flip_page = 0;
+ flip_address[0] = (byte *)current->pixels;
+ flip_address[1] = (byte *)current->pixels +
+ current->h * current->pitch;
+ VGL_FlipHWSurface(this, current);
+ }
+ }
+
+ if (! SDL_ReallocFormat(current, modes[i]->Depth, VGLCurMode->Rmask,
+ VGLCurMode->Gmask, VGLCurMode->Bmask, 0)) {
+ return NULL;
+ }
+
+ /* Update hardware acceleration info */
+ VGL_UpdateVideoInfo(this);
+
+ /* Set the blit function */
+ this->UpdateRects = VGL_DirectUpdate;
+
+ /* We're done */
+ return current;
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int VGL_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return -1;
+}
+static void VGL_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+/* We need to wait for vertical retrace on page flipped displays */
+static int VGL_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (surface == SDL_VideoSurface) {
+ SDL_mutexP(hw_lock);
+ }
+ return 0;
+}
+static void VGL_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (surface == SDL_VideoSurface) {
+ SDL_mutexV(hw_lock);
+ }
+}
+
+static int VGL_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (VGLPanScreen(VGLDisplay, 0, flip_page * surface->h) < 0) {
+ SDL_SetError("VGLPanSreen() failed");
+ return -1;
+ }
+
+ flip_page = !flip_page;
+ surface->pixels = flip_address[flip_page];
+
+ return 0;
+}
+
+static void VGL_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ return;
+}
+
+int VGL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+
+ for(i = 0; i < ncolors; i++) {
+ VGLSetPaletteIndex(firstcolor + i,
+ colors[i].r>>2,
+ colors[i].g>>2,
+ colors[i].b>>2);
+ }
+ return 1;
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void VGL_VideoQuit(_THIS)
+{
+ int i, j;
+
+ /* Return the keyboard to the normal state */
+ VGLKeyboardEnd();
+
+ /* Reset the console video mode if we actually initialised one */
+ if (VGLCurMode != NULL) {
+ VGLEnd();
+ SDL_free(VGLCurMode);
+ VGLCurMode = NULL;
+ }
+
+ /* Clear the lock mutex */
+ if (hw_lock != NULL) {
+ SDL_DestroyMutex(hw_lock);
+ hw_lock = NULL;
+ }
+
+ /* Free video mode lists */
+ for (i = 0; i < NUM_MODELISTS; i++) {
+ if (SDL_modelist[i] != NULL) {
+ for (j = 0; SDL_modelist[i][j] != NULL; ++j) {
+ SDL_free(SDL_modelist[i][j]);
+ }
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) {
+ /* Direct screen access, not a memory buffer */
+ this->screen->pixels = NULL;
+ }
+}
+
+#define VGL_RED_INDEX 0
+#define VGL_GREEN_INDEX 1
+#define VGL_BLUE_INDEX 2
+
+static VGLMode **
+VGLListModes(int depth, int mem_model)
+{
+ static VGLMode **modes = NULL;
+
+ VGLBitmap *vminfop;
+ VGLMode **modesp, *modescp;
+ video_info_t minfo;
+ int adptype, i, modenum;
+
+ if (modes == NULL) {
+ modes = SDL_malloc(sizeof(VGLMode *) * M_VESA_MODE_MAX);
+ bzero(modes, sizeof(VGLMode *) * M_VESA_MODE_MAX);
+ }
+ modesp = modes;
+
+ for (modenum = 0; modenum < M_VESA_MODE_MAX; modenum++) {
+ minfo.vi_mode = modenum;
+ if (ioctl(0, CONS_MODEINFO, &minfo) || ioctl(0, CONS_CURRENT, &adptype))
+ continue;
+ if (minfo.vi_mode != modenum)
+ continue;
+ if ((minfo.vi_flags & V_INFO_GRAPHICS) == 0)
+ continue;
+ if ((mem_model != -1) && ((minfo.vi_mem_model & mem_model) == 0))
+ continue;
+ if ((depth > 1) && (minfo.vi_depth != depth))
+ continue;
+
+ /* reallocf can fail */
+ if ((*modesp = reallocf(*modesp, sizeof(VGLMode))) == NULL)
+ return NULL;
+ modescp = *modesp;
+
+ vminfop = &(modescp->ModeInfo);
+ bzero(vminfop, sizeof(VGLBitmap));
+
+ vminfop->Type = NOBUF;
+
+ vminfop->PixelBytes = 1; /* Good default value */
+ switch (minfo.vi_mem_model) {
+ case V_INFO_MM_PLANAR:
+ /* we can handle EGA/VGA planar modes only */
+ if (!(minfo.vi_depth != 4 || minfo.vi_planes != 4
+ || (adptype != KD_EGA && adptype != KD_VGA)))
+ vminfop->Type = VIDBUF4;
+ break;
+ case V_INFO_MM_PACKED:
+ /* we can do only 256 color packed modes */
+ if (minfo.vi_depth == 8)
+ vminfop->Type = VIDBUF8;
+ break;
+ case V_INFO_MM_VGAX:
+ vminfop->Type = VIDBUF8X;
+ break;
+#if defined(__FREEBSD__) && (defined(__DragonFly__) || __FreeBSD_version >= 500000)
+ case V_INFO_MM_DIRECT:
+ vminfop->PixelBytes = minfo.vi_pixel_size;
+ switch (vminfop->PixelBytes) {
+ case 2:
+ vminfop->Type = VIDBUF16;
+ break;
+#if notyet
+ case 3:
+ vminfop->Type = VIDBUF24;
+ break;
+#endif
+ case 4:
+ vminfop->Type = VIDBUF32;
+ break;
+ default:
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ if (vminfop->Type == NOBUF)
+ continue;
+
+ switch (vminfop->Type) {
+ case VIDBUF16:
+ case VIDBUF32:
+ modescp->Rmask = ((1 << minfo.vi_pixel_fsizes[VGL_RED_INDEX]) - 1) <<
+ minfo.vi_pixel_fields[VGL_RED_INDEX];
+ modescp->Gmask = ((1 << minfo.vi_pixel_fsizes[VGL_GREEN_INDEX]) - 1) <<
+ minfo.vi_pixel_fields[VGL_GREEN_INDEX];
+ modescp->Bmask = ((1 << minfo.vi_pixel_fsizes[VGL_BLUE_INDEX]) - 1) <<
+ minfo.vi_pixel_fields[VGL_BLUE_INDEX];
+ break;
+
+ default:
+ break;
+ }
+
+ vminfop->Xsize = minfo.vi_width;
+ vminfop->Ysize = minfo.vi_height;
+ modescp->Depth = minfo.vi_depth;
+
+ /* XXX */
+ if (minfo.vi_mode >= M_VESA_BASE)
+ modescp->ModeId = _IO('V', minfo.vi_mode - M_VESA_BASE);
+ else
+ modescp->ModeId = _IO('S', minfo.vi_mode);
+
+ /* Sort list */
+ for (i = 0; modes + i < modesp ; i++) {
+ if (modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize >
+ vminfop->Xsize * modes[i]->ModeInfo.Ysize)
+ continue;
+ if ((modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize ==
+ vminfop->Xsize * vminfop->Ysize) &&
+ (modes[i]->Depth >= modescp->Depth))
+ continue;
+ *modesp = modes[i];
+ modes[i] = modescp;
+ modescp = *modesp;
+ vminfop = &(modescp->ModeInfo);
+ }
+
+ modesp++;
+ }
+
+ if (*modesp != NULL) {
+ SDL_free(*modesp);
+ *modesp = NULL;
+ }
+
+ return modes;
+}
diff --git a/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.h b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.h
new file mode 100644
index 0000000..9fc3569
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/vgl/SDL_vglvideo.h
@@ -0,0 +1,65 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_vglvideo_h
+#define _SDL_vglvideo_h
+
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <vgl.h>
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+typedef struct {
+ int ModeId;
+ int Depth;
+ int Rmask;
+ int Gmask;
+ int Bmask;
+ VGLBitmap ModeInfo;
+} VGLMode;
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ SDL_mutex *hw_lock;
+ VGLMode *VGLCurMode;
+ int flip_page;
+ byte *flip_address[2];
+};
+/* Old variable names */
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define hw_lock (this->hidden->hw_lock)
+#define VGLCurMode (this->hidden->VGLCurMode)
+#define flip_page (this->hidden->flip_page)
+#define flip_address (this->hidden->flip_address)
+
+#endif /* _SDL_vglvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_lowvideo.h b/distrib/sdl-1.2.15/src/video/wincommon/SDL_lowvideo.h
new file mode 100644
index 0000000..89d1a88
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_lowvideo.h
@@ -0,0 +1,152 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_lowvideo_h
+#define _SDL_lowvideo_h
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#ifndef SetClassLongPtr
+#define SetClassLongPtr SetClassLong
+#endif
+#ifndef GetWindowLongPtr
+#define GetWindowLongPtr GetWindowLong
+#endif
+#ifndef SetWindowLongPtr
+#define SetWindowLongPtr SetWindowLong
+#endif
+#ifndef GWLP_WNDPROC
+#define GWLP_WNDPROC GWL_WNDPROC
+#endif
+#ifndef GWLP_HINSTANCE
+#define GWLP_HINSTANCE GWL_HINSTANCE
+#endif
+#ifndef GCLP_HICON
+#define GCLP_HICON GCL_HICON
+#endif
+
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define FULLSCREEN() \
+ ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
+
+#define WINDIB_FULLSCREEN() \
+( \
+ SDL_VideoSurface && \
+ FULLSCREEN() && \
+ (((SDL_VideoSurface->flags & SDL_OPENGL ) == SDL_OPENGL ) || \
+ ((SDL_strcmp(this->name, "windib") == 0) || \
+ (SDL_strcmp(this->name, "gapi") == 0))) \
+)
+#define DDRAW_FULLSCREEN() \
+( \
+ SDL_VideoSurface && \
+ FULLSCREEN() && \
+ ((SDL_VideoSurface->flags & SDL_OPENGL ) != SDL_OPENGL ) && \
+ (SDL_strcmp(this->name, "directx") == 0) \
+)
+
+#define DINPUT_FULLSCREEN() \
+( \
+ FULLSCREEN() && \
+ (strcmp(this->name, "directx") == 0) \
+)
+
+#define DINPUT() (strcmp(this->name, "directx") == 0)
+
+/* The main window -- and a function to set it for the audio */
+#ifdef _WIN32_WCE
+extern LPWSTR SDL_Appname;
+#else
+extern LPSTR SDL_Appname;
+#endif
+extern HINSTANCE SDL_Instance;
+extern HWND SDL_Window;
+extern BOOL SDL_windowid;
+
+/* Variables and functions exported to other parts of the native video
+ subsystem (SDL_sysevents.c)
+*/
+extern void WIN_FlushMessageQueue();
+
+/* Called by windows message loop when application is activated */
+extern void (*WIN_Activate)(_THIS, BOOL active, BOOL minimized);
+
+/* Called by windows message loop when system palette is available */
+extern void (*WIN_RealizePalette)(_THIS);
+
+/* Called by windows message loop when the system palette changes */
+extern void (*WIN_PaletteChanged)(_THIS, HWND window);
+
+/* Called by windows message loop when a portion of the screen needs update */
+extern void (*WIN_WinPAINT)(_THIS, HDC hdc);
+
+/* Called by windows message loop when the message isn't handled */
+extern LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+/* The window cursor (from SDL_sysmouse.c) */
+extern HCURSOR SDL_hcursor;
+
+/* The bounds of the window in screen coordinates */
+extern RECT SDL_bounds;
+
+/* The position of the window in windowed mode */
+extern int SDL_windowX;
+extern int SDL_windowY;
+
+/* Flag -- SDL is performing a resize, rather than the user */
+extern int SDL_resizing;
+
+/* Flag -- the mouse is in relative motion mode */
+extern int mouse_relative;
+
+/* The GDI fullscreen mode currently active */
+#ifndef NO_CHANGEDISPLAYSETTINGS
+extern DEVMODE SDL_desktop_mode;
+extern DEVMODE SDL_fullscreen_mode;
+#endif
+
+/* The system gamma ramp for GDI modes */
+extern WORD *gamma_saved;
+
+/* This is really from SDL_dx5audio.c */
+extern void DX5_SoundFocus(HWND window);
+
+/* DJM: This is really from SDL_sysevents.c, we need it in
+ GDL_CreateWindow as well */
+LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#ifdef _WIN64
+#define SDL_ToUnicode ToUnicode
+#else
+/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
+typedef int (WINAPI *ToUnicodeFN)(UINT, UINT, const BYTE *, LPWSTR, int, UINT);
+
+extern ToUnicodeFN SDL_ToUnicode;
+#endif
+
+#endif /* SDL_lowvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysevents.c b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysevents.c
new file mode 100644
index 0000000..76c67a1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysevents.c
@@ -0,0 +1,855 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */
+#ifndef WM_XBUTTONDOWN
+#define WM_XBUTTONDOWN 0x020B
+#endif
+#ifndef WM_XBUTTONUP
+#define WM_XBUTTONUP 0x020C
+#endif
+#ifndef GET_XBUTTON_WPARAM
+#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
+#endif
+
+#include "SDL_events.h"
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_lowvideo.h"
+#include "SDL_syswm_c.h"
+#include "SDL_main.h"
+#include "SDL_loadso.h"
+
+#ifdef WMMSG_DEBUG
+#include "wmmsg.h"
+#endif
+
+#include "../windib/SDL_gapidibvideo.h"
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+#include "../gapi/SDL_gapivideo.h"
+#endif
+
+#ifdef _WIN32_WCE
+#define IsZoomed(HWND) 1
+#define NO_GETKEYBOARDSTATE
+#if _WIN32_WCE < 420
+#define NO_CHANGEDISPLAYSETTINGS
+#endif
+#endif
+
+/* The window we use for everything... */
+#ifdef _WIN32_WCE
+LPWSTR SDL_Appname = NULL;
+#else
+LPSTR SDL_Appname = NULL;
+#endif
+Uint32 SDL_Appstyle = 0;
+HINSTANCE SDL_Instance = NULL;
+HWND SDL_Window = NULL;
+RECT SDL_bounds = {0, 0, 0, 0};
+int SDL_windowX = 0;
+int SDL_windowY = 0;
+int SDL_resizing = 0;
+int mouse_relative = 0;
+int posted = 0;
+#ifndef NO_CHANGEDISPLAYSETTINGS
+DEVMODE SDL_desktop_mode;
+DEVMODE SDL_fullscreen_mode;
+#endif
+WORD *gamma_saved = NULL;
+
+
+/* Functions called by the message processing function */
+LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL;
+void (*WIN_Activate)(_THIS, BOOL active, BOOL iconic);
+void (*WIN_RealizePalette)(_THIS);
+void (*WIN_PaletteChanged)(_THIS, HWND window);
+void (*WIN_WinPAINT)(_THIS, HDC hdc);
+extern void DIB_SwapGamma(_THIS);
+
+#ifndef NO_GETKEYBOARDSTATE
+#ifndef _WIN64
+/* Variables and support functions for SDL_ToUnicode() */
+static int codepage;
+static int Is9xME();
+static int GetCodePage();
+static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, const BYTE *keystate, LPWSTR wchars, int wsize, UINT flags);
+
+ToUnicodeFN SDL_ToUnicode = ToUnicode9xME;
+#endif
+#endif /* !NO_GETKEYBOARDSTATE */
+
+
+#if defined(_WIN32_WCE)
+
+//AdjustWindowRect is not available under WinCE 2003
+#define AdjustWindowRect(a,b,c) (AdjustWindowRectEx((a),(b),(c),0))
+
+// dynamically load aygshell dll because we want SDL to work on HPC and be300
+HINSTANCE aygshell = NULL;
+BOOL (WINAPI *SHFullScreen)(HWND hwndRequester, DWORD dwState) = 0;
+
+#define SHFS_SHOWTASKBAR 0x0001
+#define SHFS_HIDETASKBAR 0x0002
+#define SHFS_SHOWSIPBUTTON 0x0004
+#define SHFS_HIDESIPBUTTON 0x0008
+#define SHFS_SHOWSTARTICON 0x0010
+#define SHFS_HIDESTARTICON 0x0020
+
+static void LoadAygshell(void)
+{
+ if( !aygshell )
+ aygshell = SDL_LoadObject("aygshell.dll");
+ if( (aygshell != 0) && (SHFullScreen == 0) )
+ {
+ SHFullScreen = (int (WINAPI *)(struct HWND__ *,unsigned long)) SDL_LoadFunction(aygshell, "SHFullScreen");
+ }
+}
+
+#endif
+
+/* JC 14 Mar 2006
+ This is used all over the place, in the windib driver and in the dx5 driver
+ So we may as well stick it here instead of having multiple copies scattered
+ about
+*/
+void WIN_FlushMessageQueue()
+{
+ MSG msg;
+ while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
+ if ( msg.message == WM_QUIT ) break;
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+}
+
+static void SDL_RestoreGameMode(void)
+{
+#ifdef _WIN32_WCE //Under ce we don't minimize, therefore no restore
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+ SDL_VideoDevice *this = current_video;
+ if(SDL_strcmp(this->name, "gapi") == 0)
+ {
+ if( this->hidden->gapiInfo->suspended )
+ {
+ this->hidden->gapiInfo->suspended = 0;
+ }
+ }
+#endif
+
+#else
+ ShowWindow(SDL_Window, SW_RESTORE);
+#endif
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+#ifndef _WIN32_WCE
+ ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
+#endif
+#endif /* NO_CHANGEDISPLAYSETTINGS */
+}
+static void SDL_RestoreDesktopMode(void)
+{
+
+#ifdef _WIN32_WCE
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+ SDL_VideoDevice *this = current_video;
+ if(SDL_strcmp(this->name, "gapi") == 0)
+ {
+ if( !this->hidden->gapiInfo->suspended )
+ {
+ this->hidden->gapiInfo->suspended = 1;
+ }
+ }
+#endif
+
+#else
+ /* WinCE does not have a taskbar, so minimizing is not convenient */
+ ShowWindow(SDL_Window, SW_MINIMIZE);
+#endif
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+#ifndef _WIN32_WCE
+ ChangeDisplaySettings(NULL, 0);
+#endif
+#endif /* NO_CHANGEDISPLAYSETTINGS */
+}
+
+#ifdef WM_MOUSELEAVE
+/*
+ Special code to handle mouse leave events - this sucks...
+ http://support.microsoft.com/support/kb/articles/q183/1/07.asp
+
+ TrackMouseEvent() is only available on Win98 and WinNT.
+ _TrackMouseEvent() is available on Win95, but isn't yet in the mingw32
+ development environment, and only works on systems that have had IE 3.0
+ or newer installed on them (which is not the case with the base Win95).
+ Therefore, we implement our own version of _TrackMouseEvent() which
+ uses our own implementation if TrackMouseEvent() is not available.
+*/
+static BOOL (WINAPI *_TrackMouseEvent)(TRACKMOUSEEVENT *ptme) = NULL;
+
+static VOID CALLBACK
+TrackMouseTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
+{
+ union { RECT rect; POINT pt; } rectpt; /* prevent type-punning issue. */
+ POINT pt;
+
+ GetClientRect(hWnd, &rectpt.rect);
+ MapWindowPoints(hWnd, NULL, &rectpt.pt, 2);
+ GetCursorPos(&pt);
+ if ( !PtInRect(&rectpt.rect, pt) || (WindowFromPoint(pt) != hWnd) ) {
+ if ( !KillTimer(hWnd, idEvent) ) {
+ /* Error killing the timer! */
+ }
+ PostMessage(hWnd, WM_MOUSELEAVE, 0, 0);
+ }
+}
+static BOOL WINAPI WIN_TrackMouseEvent(TRACKMOUSEEVENT *ptme)
+{
+ if ( ptme->dwFlags == TME_LEAVE ) {
+ return SetTimer(ptme->hwndTrack, ptme->dwFlags, 100,
+ (TIMERPROC)TrackMouseTimerProc) != 0;
+ }
+ return FALSE;
+}
+#endif /* WM_MOUSELEAVE */
+
+int sysevents_mouse_pressed = 0;
+
+/* The main Win32 event handler
+DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it
+*/
+LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ SDL_VideoDevice *this = current_video;
+#ifdef WMMSG_DEBUG
+ fprintf(stderr, "Received windows message: ");
+ if ( msg > MAX_WMMSG ) {
+ fprintf(stderr, "%d", msg);
+ } else {
+ fprintf(stderr, "%s", wmtab[msg]);
+ }
+ fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam);
+#endif
+ switch (msg) {
+
+ case WM_ACTIVATE: {
+ SDL_VideoDevice *this = current_video;
+ BOOL active, minimized;
+ Uint8 appstate;
+
+ minimized = HIWORD(wParam);
+ active = (LOWORD(wParam) != WA_INACTIVE) && !minimized;
+ if ( active ) {
+ /* Gain the following states */
+ appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS;
+ if ( !(SDL_GetAppState() & SDL_APPINPUTFOCUS) ) {
+ if ( this->input_grab != SDL_GRAB_OFF ) {
+ WIN_GrabInput(this, SDL_GRAB_ON);
+ }
+ if ( ! DDRAW_FULLSCREEN() ) {
+ DIB_SwapGamma(this);
+ }
+ if ( WINDIB_FULLSCREEN() ) {
+ SDL_RestoreGameMode();
+ }
+ }
+#if defined(_WIN32_WCE)
+ if ( WINDIB_FULLSCREEN() ) {
+ LoadAygshell();
+ if( SHFullScreen )
+ SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
+ else
+ ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
+ }
+#endif
+ posted = SDL_PrivateAppActive(1, appstate);
+ } else {
+ /* Lose the following states */
+ appstate = SDL_APPINPUTFOCUS;
+ if ( minimized ) {
+ appstate |= SDL_APPACTIVE;
+ }
+
+ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
+ if ( this->input_grab != SDL_GRAB_OFF ) {
+ WIN_GrabInput(this, SDL_GRAB_OFF);
+ }
+ if ( ! DDRAW_FULLSCREEN() ) {
+ DIB_SwapGamma(this);
+ }
+ if ( WINDIB_FULLSCREEN() ) {
+ appstate |= SDL_APPMOUSEFOCUS;
+ SDL_RestoreDesktopMode();
+ /* A fullscreen app gets hidden but will not get a minimize event */
+ appstate |= (SDL_APPACTIVE | SDL_APPMOUSEFOCUS);
+#if defined(_WIN32_WCE)
+ LoadAygshell();
+ if( SHFullScreen )
+ SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
+ else
+ ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW);
+#endif
+ }
+ }
+ posted = SDL_PrivateAppActive(0, appstate);
+ }
+ WIN_Activate(this, active, minimized);
+ return(0);
+ }
+ break;
+
+ case WM_MOUSEMOVE: {
+
+#ifdef WM_MOUSELEAVE
+ if ( SDL_VideoSurface ) {
+ /* mouse has entered the window */
+
+ if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ TRACKMOUSEEVENT tme;
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = SDL_Window;
+ _TrackMouseEvent(&tme);
+ }
+ }
+#endif /* WM_MOUSELEAVE */
+
+ /* Mouse motion is handled in DIB_PumpEvents or
+ * DX5_PumpEvents, depending on the video driver
+ * in use */
+
+ posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ }
+ return(0);
+
+#ifdef WM_MOUSELEAVE
+ case WM_MOUSELEAVE: {
+
+ if ( SDL_VideoSurface ) {
+ /* mouse has left the window */
+ posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+ }
+ return(0);
+#endif /* WM_MOUSELEAVE */
+
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP: {
+ /* Mouse is handled by DirectInput when fullscreen */
+ if ( SDL_VideoSurface && ! DINPUT() ) {
+ WORD xbuttonval = 0;
+ Uint8 button, state;
+ int x, y;
+
+ /* DJM:
+ We want the SDL window to take focus so that
+ it acts like a normal windows "component"
+ (e.g. gains keyboard focus on a mouse click).
+ */
+ SetFocus(SDL_Window);
+
+ /* Figure out which button to use */
+ switch (msg) {
+ case WM_LBUTTONDOWN:
+ button = SDL_BUTTON_LEFT;
+ state = SDL_PRESSED;
+ break;
+ case WM_LBUTTONUP:
+ button = SDL_BUTTON_LEFT;
+ state = SDL_RELEASED;
+ break;
+ case WM_MBUTTONDOWN:
+ button = SDL_BUTTON_MIDDLE;
+ state = SDL_PRESSED;
+ break;
+ case WM_MBUTTONUP:
+ button = SDL_BUTTON_MIDDLE;
+ state = SDL_RELEASED;
+ break;
+ case WM_RBUTTONDOWN:
+ button = SDL_BUTTON_RIGHT;
+ state = SDL_PRESSED;
+ break;
+ case WM_RBUTTONUP:
+ button = SDL_BUTTON_RIGHT;
+ state = SDL_RELEASED;
+ break;
+ case WM_XBUTTONDOWN:
+ xbuttonval = GET_XBUTTON_WPARAM(wParam);
+ button = SDL_BUTTON_X1 + xbuttonval - 1;
+ state = SDL_PRESSED;
+ break;
+ case WM_XBUTTONUP:
+ xbuttonval = GET_XBUTTON_WPARAM(wParam);
+ button = SDL_BUTTON_X1 + xbuttonval - 1;
+ state = SDL_RELEASED;
+ break;
+ default:
+ /* Eh? Unknown button? */
+ return(0);
+ }
+ if ( state == SDL_PRESSED ) {
+ /* Grab mouse so we get up events */
+ if ( ++sysevents_mouse_pressed > 0 ) {
+ SetCapture(hwnd);
+ }
+ } else {
+ /* Release mouse after all up events */
+ if ( --sysevents_mouse_pressed <= 0 ) {
+ ReleaseCapture();
+ sysevents_mouse_pressed = 0;
+ }
+ }
+ if ( mouse_relative ) {
+ /* RJR: March 28, 2000
+ report internal mouse position if in relative mode */
+ x = 0; y = 0;
+ } else {
+ x = (Sint16)LOWORD(lParam);
+ y = (Sint16)HIWORD(lParam);
+#ifdef _WIN32_WCE
+ if (SDL_VideoSurface)
+ GapiTransform(this->hidden->userOrientation,
+this->hidden->hiresFix, &x, &y);
+#endif
+ }
+ posted = SDL_PrivateMouseButton(
+ state, button, x, y);
+
+ /*
+ * MSDN says:
+ * "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP
+ * messages, an application should return TRUE from [an
+ * XBUTTON message] if it processes it. Doing so will allow
+ * software that simulates this message on Microsoft Windows
+ * systems earlier than Windows 2000 to determine whether
+ * the window procedure processed the message or called
+ * DefWindowProc to process it.
+ */
+ if (xbuttonval > 0)
+ return(TRUE);
+ }
+ }
+ return(0);
+
+
+#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
+ case WM_MOUSEWHEEL:
+ if ( SDL_VideoSurface && ! DINPUT() ) {
+ int move = (short)HIWORD(wParam);
+ if ( move ) {
+ Uint8 button;
+ if ( move > 0 )
+ button = SDL_BUTTON_WHEELUP;
+ else
+ button = SDL_BUTTON_WHEELDOWN;
+ posted = SDL_PrivateMouseButton(
+ SDL_PRESSED, button, 0, 0);
+ posted |= SDL_PrivateMouseButton(
+ SDL_RELEASED, button, 0, 0);
+ }
+ }
+ return(0);
+#endif
+
+#ifdef WM_GETMINMAXINFO
+ /* This message is sent as a way for us to "check" the values
+ * of a position change. If we don't like it, we can adjust
+ * the values before they are changed.
+ */
+ case WM_GETMINMAXINFO: {
+ MINMAXINFO *info;
+ RECT size;
+ int x, y;
+ int style;
+ int width;
+ int height;
+
+ /* We don't want to clobber an internal resize */
+ if ( SDL_resizing )
+ return(0);
+
+ /* We allow resizing with the SDL_RESIZABLE flag */
+ if ( SDL_PublicSurface &&
+ (SDL_PublicSurface->flags & SDL_RESIZABLE) ) {
+ return(0);
+ }
+
+ /* Get the current position of our window */
+ GetWindowRect(SDL_Window, &size);
+ x = size.left;
+ y = size.top;
+
+ /* Calculate current width and height of our window */
+ size.top = 0;
+ size.left = 0;
+ if ( SDL_PublicSurface != NULL ) {
+ size.bottom = SDL_PublicSurface->h;
+ size.right = SDL_PublicSurface->w;
+ } else {
+ size.bottom = 0;
+ size.right = 0;
+ }
+
+ /* DJM - according to the docs for GetMenu(), the
+ return value is undefined if hwnd is a child window.
+ Aparently it's too difficult for MS to check
+ inside their function, so I have to do it here.
+ */
+ style = GetWindowLong(hwnd, GWL_STYLE);
+ AdjustWindowRect(
+ &size,
+ style,
+ style & WS_CHILDWINDOW ? FALSE
+ : GetMenu(hwnd) != NULL);
+
+ width = size.right - size.left;
+ height = size.bottom - size.top;
+
+ /* Fix our size to the current size */
+ info = (MINMAXINFO *)lParam;
+ info->ptMaxSize.x = width;
+ info->ptMaxSize.y = height;
+ info->ptMaxPosition.x = x;
+ info->ptMaxPosition.y = y;
+ info->ptMinTrackSize.x = width;
+ info->ptMinTrackSize.y = height;
+ info->ptMaxTrackSize.x = width;
+ info->ptMaxTrackSize.y = height;
+ }
+ return(0);
+#endif /* WM_GETMINMAXINFO */
+
+ case WM_WINDOWPOSCHANGING: {
+ WINDOWPOS *windowpos = (WINDOWPOS*)lParam;
+
+ /* When menu is at the side or top, Windows likes
+ to try to reposition the fullscreen window when
+ changing video modes.
+ */
+ if ( !SDL_resizing &&
+ SDL_PublicSurface &&
+ (SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
+ windowpos->x = 0;
+ windowpos->y = 0;
+ }
+ }
+ return(0);
+
+ case WM_WINDOWPOSCHANGED: {
+ SDL_VideoDevice *this = current_video;
+ POINT pt;
+ int w, h;
+
+ GetClientRect(SDL_Window, &SDL_bounds);
+
+ /* avoiding type-punning here... */
+ pt.x = SDL_bounds.left;
+ pt.y = SDL_bounds.top;
+ ClientToScreen(SDL_Window, &pt);
+ SDL_bounds.left = pt.x;
+ SDL_bounds.top = pt.y;
+
+ pt.x = SDL_bounds.right;
+ pt.y = SDL_bounds.bottom;
+ ClientToScreen(SDL_Window, &pt);
+ SDL_bounds.right = pt.x;
+ SDL_bounds.bottom = pt.y;
+
+ if ( !SDL_resizing && !IsZoomed(SDL_Window) &&
+ SDL_PublicSurface &&
+ !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
+ SDL_windowX = SDL_bounds.left;
+ SDL_windowY = SDL_bounds.top;
+ }
+ w = SDL_bounds.right-SDL_bounds.left;
+ h = SDL_bounds.bottom-SDL_bounds.top;
+ if ( this->input_grab != SDL_GRAB_OFF ) {
+ ClipCursor(&SDL_bounds);
+ }
+ if ( SDL_PublicSurface &&
+ (SDL_PublicSurface->flags & SDL_RESIZABLE) ) {
+ SDL_PrivateResize(w, h);
+ }
+ }
+ break;
+
+ /* We need to set the cursor */
+ case WM_SETCURSOR: {
+ Uint16 hittest;
+
+ hittest = LOWORD(lParam);
+ if ( hittest == HTCLIENT ) {
+ SetCursor(SDL_hcursor);
+ return(TRUE);
+ }
+ }
+ break;
+
+ /* We are about to get palette focus! */
+ case WM_QUERYNEWPALETTE: {
+ WIN_RealizePalette(current_video);
+ return(TRUE);
+ }
+ break;
+
+ /* Another application changed the palette */
+ case WM_PALETTECHANGED: {
+ WIN_PaletteChanged(current_video, (HWND)wParam);
+ }
+ break;
+
+ /* We were occluded, refresh our display */
+ case WM_PAINT: {
+ HDC hdc;
+ PAINTSTRUCT ps;
+
+ hdc = BeginPaint(SDL_Window, &ps);
+ if ( current_video->screen &&
+ !(current_video->screen->flags & SDL_OPENGL) ) {
+ WIN_WinPAINT(current_video, hdc);
+ }
+ EndPaint(SDL_Window, &ps);
+ }
+ return(0);
+
+ /* DJM: Send an expose event in this case */
+ case WM_ERASEBKGND: {
+ posted = SDL_PrivateExpose();
+ }
+ return(0);
+
+ case WM_CLOSE: {
+ if ( (posted = SDL_PrivateQuit()) )
+ PostQuitMessage(0);
+ }
+ return(0);
+
+ case WM_DESTROY: {
+ PostQuitMessage(0);
+ }
+ return(0);
+
+#ifndef NO_GETKEYBOARDSTATE
+ case WM_INPUTLANGCHANGE:
+#ifndef _WIN64
+ codepage = GetCodePage();
+#endif
+ return(TRUE);
+#endif
+
+ default: {
+ /* Special handling by the video driver */
+ if (HandleMessage) {
+ return(HandleMessage(current_video,
+ hwnd, msg, wParam, lParam));
+ }
+ }
+ break;
+ }
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+}
+
+/* Allow the application handle to be stored and retrieved later */
+static void *SDL_handle = NULL;
+
+void SDL_SetModuleHandle(void *handle)
+{
+ SDL_handle = handle;
+}
+void *SDL_GetModuleHandle(void)
+{
+ void *handle;
+
+ if ( SDL_handle ) {
+ handle = SDL_handle;
+ } else {
+ handle = GetModuleHandle(NULL);
+ }
+ return(handle);
+}
+
+/* This allows the SDL_WINDOWID hack */
+BOOL SDL_windowid = FALSE;
+
+static int app_registered = 0;
+
+/* Register the class for this application -- exported for winmain.c */
+int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
+{
+ WNDCLASS class;
+#ifdef WM_MOUSELEAVE
+ HMODULE handle;
+#endif
+
+ /* Only do this once... */
+ if ( app_registered ) {
+ ++app_registered;
+ return(0);
+ }
+
+#ifndef CS_BYTEALIGNCLIENT
+#define CS_BYTEALIGNCLIENT 0
+#endif
+ if ( ! name && ! SDL_Appname ) {
+ name = "SDL_app";
+ SDL_Appstyle = CS_BYTEALIGNCLIENT;
+ SDL_Instance = hInst ? hInst : SDL_GetModuleHandle();
+ }
+
+ if ( name ) {
+#ifdef _WIN32_WCE
+ /* WinCE uses the UNICODE version */
+ SDL_Appname = SDL_iconv_utf8_ucs2(name);
+#else
+ SDL_Appname = SDL_iconv_utf8_locale(name);
+#endif /* _WIN32_WCE */
+ SDL_Appstyle = style;
+ SDL_Instance = hInst ? hInst : SDL_GetModuleHandle();
+ }
+
+ /* Register the application class */
+ class.hCursor = NULL;
+ class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
+ IMAGE_ICON,
+ 0, 0, LR_DEFAULTCOLOR);
+ class.lpszMenuName = NULL;
+ class.lpszClassName = SDL_Appname;
+ class.hbrBackground = NULL;
+ class.hInstance = SDL_Instance;
+ class.style = SDL_Appstyle;
+#if SDL_VIDEO_OPENGL
+ class.style |= CS_OWNDC;
+#endif
+ class.lpfnWndProc = WinMessage;
+ class.cbWndExtra = 0;
+ class.cbClsExtra = 0;
+ if ( ! RegisterClass(&class) ) {
+ SDL_SetError("Couldn't register application class");
+ return(-1);
+ }
+
+#ifdef WM_MOUSELEAVE
+ /* Get the version of TrackMouseEvent() we use */
+ _TrackMouseEvent = NULL;
+ handle = GetModuleHandle("USER32.DLL");
+ if ( handle ) {
+ _TrackMouseEvent = (BOOL (WINAPI *)(TRACKMOUSEEVENT *))GetProcAddress(handle, "TrackMouseEvent");
+ }
+ if ( _TrackMouseEvent == NULL ) {
+ _TrackMouseEvent = WIN_TrackMouseEvent;
+ }
+#endif /* WM_MOUSELEAVE */
+
+#ifndef NO_GETKEYBOARDSTATE
+#ifndef _WIN64
+ /* Initialise variables for SDL_ToUnicode() */
+ codepage = GetCodePage();
+
+ /* Cygwin headers don't match windows.h, so we have to cast around a
+ const issue here... */
+ SDL_ToUnicode = Is9xME() ? ToUnicode9xME : (ToUnicodeFN) ToUnicode;
+#endif
+#endif /* NO_GETKEYBOARDSTATE */
+
+ app_registered = 1;
+ return(0);
+}
+
+/* Unregisters the windowclass registered in SDL_RegisterApp above. */
+void SDL_UnregisterApp()
+{
+ WNDCLASS class;
+
+ /* SDL_RegisterApp might not have been called before */
+ if ( !app_registered ) {
+ return;
+ }
+ --app_registered;
+ if ( app_registered == 0 ) {
+ /* Check for any registered window classes. */
+ if ( GetClassInfo(SDL_Instance, SDL_Appname, &class) ) {
+ UnregisterClass(SDL_Appname, SDL_Instance);
+ }
+ SDL_free(SDL_Appname);
+ SDL_Appname = NULL;
+ }
+}
+
+#ifndef NO_GETKEYBOARDSTATE
+#ifndef _WIN64
+/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
+
+static int Is9xME()
+{
+ OSVERSIONINFO info;
+
+ SDL_memset(&info, 0, sizeof(info));
+ info.dwOSVersionInfoSize = sizeof(info);
+ if (!GetVersionEx(&info)) {
+ return 0;
+ }
+ return (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+}
+
+static int GetCodePage()
+{
+ char buff[8];
+ int lcid = MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT);
+ int cp = GetACP();
+
+ if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof(buff))) {
+ cp = SDL_atoi(buff);
+ }
+ return cp;
+}
+
+static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, const BYTE *keystate, LPWSTR wchars, int wsize, UINT flags)
+{
+ BYTE chars[2];
+
+ /* arg #3 should be const BYTE *, but cygwin lists it as PBYTE. */
+ if (ToAsciiEx(vkey, scancode, (PBYTE) keystate, (WORD*)chars, 0, GetKeyboardLayout(0)) == 1) {
+ return MultiByteToWideChar(codepage, 0, (LPCSTR) chars, 1, wchars, wsize);
+ }
+ return 0;
+}
+#endif
+#endif /* !NO_GETKEYBOARDSTATE */
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse.c b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse.c
new file mode 100644
index 0000000..12d17e0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse.c
@@ -0,0 +1,259 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_sysmouse_c.h"
+#include "SDL_lowvideo.h"
+
+#ifdef _WIN32_WCE
+#define USE_STATIC_CURSOR
+#endif
+
+HCURSOR SDL_hcursor = NULL; /* Exported for SDL_eventloop.c */
+
+/* The implementation dependent data for the window manager cursor */
+/* For some reason when creating a windows cursor, the ands and xors memory
+ is not copied, so we need to keep track of it and free it when we are done
+ with the cursor. If we free the memory prematurely, the app crashes. :-}
+*/
+struct WMcursor {
+ HCURSOR curs;
+#ifndef USE_STATIC_CURSOR
+ Uint8 *ands;
+ Uint8 *xors;
+#endif
+};
+
+/* Convert bits to padded bytes */
+#define PAD_BITS(bits) ((bits+7)/8)
+
+#ifdef CURSOR_DEBUG
+static void PrintBITMAP(FILE *out, char *bits, int w, int h)
+{
+ int i;
+ unsigned char ch;
+
+ while ( h-- > 0 ) {
+ for ( i=0; i<w; ++i ) {
+ if ( (i%8) == 0 )
+ ch = *bits++;
+ if ( ch&0x80 )
+ fprintf(out, "X");
+ else
+ fprintf(out, " ");
+ ch <<= 1;
+ }
+ fprintf(out, "\n");
+ }
+}
+#endif
+
+#ifndef USE_STATIC_CURSOR
+/* Local functions to convert the SDL cursor mask into Windows 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++);
+}
+#endif /* !USE_STATIC_CURSOR */
+
+void WIN_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+#ifndef USE_STATIC_CURSOR
+ if ( cursor->curs == GetCursor() )
+ SetCursor(NULL);
+ if ( cursor->curs != NULL )
+ DestroyCursor(cursor->curs);
+ if ( cursor->ands != NULL )
+ SDL_free(cursor->ands);
+ if ( cursor->xors != NULL )
+ SDL_free(cursor->xors);
+#endif /* !USE_STATIC_CURSOR */
+ SDL_free(cursor);
+}
+
+WMcursor *WIN_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+#ifdef USE_STATIC_CURSOR
+ WMcursor *cursor;
+
+ /* Allocate the cursor */
+ cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
+ if ( cursor ) {
+ cursor->curs = LoadCursor(NULL, IDC_ARROW);
+ }
+ return(cursor);
+#else
+ WMcursor *cursor;
+ int allowed_x;
+ int allowed_y;
+ int run, pad, i;
+ Uint8 *aptr, *xptr;
+
+ /* Check to make sure the cursor size is okay */
+ allowed_x = GetSystemMetrics(SM_CXCURSOR);
+ allowed_y = GetSystemMetrics(SM_CYCURSOR);
+ if ( (w > allowed_x) || (h > allowed_y) ) {
+ SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
+ allowed_x, allowed_y);
+ return(NULL);
+ }
+
+ /* Allocate the cursor */
+ cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
+ if ( cursor == NULL ) {
+ SDL_SetError("Out of memory");
+ return(NULL);
+ }
+ cursor->curs = NULL;
+ cursor->ands = NULL;
+ cursor->xors = NULL;
+
+ /* Pad out to the normal cursor size */
+ run = PAD_BITS(w);
+ pad = PAD_BITS(allowed_x)-run;
+ aptr = cursor->ands = (Uint8 *)SDL_malloc((run+pad)*allowed_y);
+ xptr = cursor->xors = (Uint8 *)SDL_malloc((run+pad)*allowed_y);
+ if ( (aptr == NULL) || (xptr == NULL) ) {
+ WIN_FreeWMCursor(NULL, cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ for ( i=0; i<h; ++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<allowed_y; ++i ) {
+ SDL_memset(xptr, 0, pad);
+ xptr += pad;
+ SDL_memset(aptr, ~0, pad);
+ aptr += pad;
+ }
+
+ /* Create the cursor */
+ cursor->curs = CreateCursor(
+ (HINSTANCE)GetWindowLongPtr(SDL_Window, GWLP_HINSTANCE),
+ hot_x, hot_y, allowed_x, allowed_y,
+ cursor->ands, cursor->xors);
+ if ( cursor->curs == NULL ) {
+ WIN_FreeWMCursor(NULL, cursor);
+ SDL_SetError("Windows couldn't create the requested cursor");
+ return(NULL);
+ }
+ return(cursor);
+#endif /* USE_STATIC_CURSOR */
+}
+
+int WIN_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ POINT mouse_pos;
+
+ if ( !this->screen ) {
+ return(0);
+ }
+
+ /* Set the window cursor to our cursor, if applicable */
+ if ( cursor != NULL ) {
+ SDL_hcursor = cursor->curs;
+ } else {
+ SDL_hcursor = NULL;
+ }
+ GetCursorPos(&mouse_pos);
+ if ( PtInRect(&SDL_bounds, mouse_pos) ) {
+ SetCursor(SDL_hcursor);
+ }
+ return(1);
+}
+
+void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ if ( mouse_relative) {
+ /* RJR: March 28, 2000
+ leave physical cursor at center of screen if
+ mouse hidden and grabbed */
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ } else {
+ POINT pt;
+
+ /* With DirectInput the position doesn't follow
+ * the cursor, so it is set manually */
+ if ( DINPUT() ) {
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ }
+
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(SDL_Window, &pt);
+ SetCursorPos(pt.x, pt.y);
+ }
+}
+
+/* Update the current mouse state and position */
+void WIN_UpdateMouse(_THIS)
+{
+ POINT pt;
+
+ /* Always unset SDL_APPMOUSEFOCUS to give the WM_MOUSEMOVE event
+ * handler a chance to install a TRACKMOUSEEVENT */
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+
+ GetCursorPos(&pt);
+ ScreenToClient(SDL_Window, &pt);
+ SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
+}
+
+/* Check to see if we need to enter or leave mouse relative mode */
+void WIN_CheckMouseMode(_THIS)
+{
+#ifndef _WIN32_WCE
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
+ (this->input_grab != SDL_GRAB_OFF) ) {
+ mouse_relative = 1;
+ } else {
+ mouse_relative = 0;
+ }
+#else
+ mouse_relative = 0;
+#endif
+}
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse_c.h b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse_c.h
new file mode 100644
index 0000000..5d5fe8d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_sysmouse_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Functions to be exported */
+extern void WIN_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *WIN_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int WIN_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+extern void WIN_UpdateMouse(_THIS);
+extern void WIN_CheckMouseMode(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm.c b/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm.c
new file mode 100644
index 0000000..504d95d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm.c
@@ -0,0 +1,297 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "SDL_version.h"
+#include "SDL_video.h"
+#include "SDL_loadso.h"
+#include "SDL_syswm.h"
+#include "../SDL_pixels_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_syswm_c.h"
+#include "SDL_wingl_c.h"
+
+
+#ifdef _WIN32_WCE
+#define DISABLE_ICON_SUPPORT
+#endif
+
+/* The screen icon -- needs to be freed on SDL_VideoQuit() */
+HICON screen_icn = NULL;
+
+/* Win32 icon mask semantics are different from those of SDL:
+ SDL applies the mask to the icon and copies result to desktop.
+ Win32 applies the mask to the desktop and XORs the icon on.
+ This means that the SDL mask needs to be applied to the icon and
+ then inverted and passed to Win32.
+*/
+void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
+{
+#ifdef DISABLE_ICON_SUPPORT
+ return;
+#else
+ SDL_Palette *pal_256;
+ SDL_Surface *icon_256;
+ Uint8 *pdata, *pwin32;
+ Uint8 *mdata, *mwin32, m = 0;
+ int icon_len;
+ int icon_plen;
+ int icon_mlen;
+ int icon_pitch;
+ int mask_pitch;
+ SDL_Rect bounds;
+ int i, skip;
+ int row, col;
+ struct /* quasi-BMP format */ Win32Icon {
+ Uint32 biSize;
+ Sint32 biWidth;
+ Sint32 biHeight;
+ Uint16 biPlanes;
+ Uint16 biBitCount;
+ Uint32 biCompression;
+ Uint32 biSizeImage;
+ Sint32 biXPelsPerMeter;
+ Sint32 biYPelsPerMeter;
+ Uint32 biClrUsed;
+ Uint32 biClrImportant;
+ struct /* RGBQUAD -- note it's BGR ordered */ {
+ Uint8 rgbBlue;
+ Uint8 rgbGreen;
+ Uint8 rgbRed;
+ Uint8 rgbReserved;
+ } biColors[256];
+ /* Pixels:
+ Uint8 pixels[]
+ */
+ /* Mask:
+ Uint8 mask[]
+ */
+ } *icon_win32;
+
+ /* Allocate the win32 bmp icon and set everything to zero */
+ icon_pitch = ((icon->w+3)&~3);
+ mask_pitch = ((icon->w+7)/8);
+ icon_plen = icon->h*icon_pitch;
+ icon_mlen = icon->h*mask_pitch;
+ icon_len = sizeof(*icon_win32)+icon_plen+icon_mlen;
+ icon_win32 = (struct Win32Icon *)SDL_stack_alloc(Uint8, icon_len);
+ if ( icon_win32 == NULL ) {
+ return;
+ }
+ SDL_memset(icon_win32, 0, icon_len);
+
+ /* Set the basic BMP parameters */
+ icon_win32->biSize = sizeof(*icon_win32)-sizeof(icon_win32->biColors);
+ icon_win32->biWidth = icon->w;
+ icon_win32->biHeight = icon->h*2;
+ icon_win32->biPlanes = 1;
+ icon_win32->biBitCount = 8;
+ icon_win32->biSizeImage = icon_plen+icon_mlen;
+
+ /* Allocate a standard 256 color icon surface */
+ icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
+ icon_win32->biBitCount, 0, 0, 0, 0);
+ if ( icon_256 == NULL ) {
+ SDL_stack_free(icon_win32);
+ return;
+ }
+ pal_256 = icon_256->format->palette;
+ if (icon->format->palette &&
+ (icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)){
+ Uint8 black;
+ SDL_memcpy(pal_256->colors, icon->format->palette->colors,
+ pal_256->ncolors*sizeof(SDL_Color));
+ /* Make sure that 0 is black! */
+ black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00);
+ pal_256->colors[black] = pal_256->colors[0];
+ pal_256->colors[0].r = 0x00;
+ pal_256->colors[0].g = 0x00;
+ pal_256->colors[0].b = 0x00;
+ } else {
+ SDL_DitherColors(pal_256->colors,
+ icon_256->format->BitsPerPixel);
+ }
+
+ /* Now copy color data to the icon BMP */
+ for ( i=0; i<(1<<icon_win32->biBitCount); ++i ) {
+ icon_win32->biColors[i].rgbRed = pal_256->colors[i].r;
+ icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g;
+ icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b;
+ }
+
+ /* Convert icon to a standard surface format. This may not always
+ be necessary, as Windows supports a variety of BMP formats, but
+ it greatly simplifies our code.
+ */
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = icon->w;
+ bounds.h = icon->h;
+ if ( SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0 ) {
+ SDL_stack_free(icon_win32);
+ SDL_FreeSurface(icon_256);
+ return;
+ }
+
+ /* Copy pixels upside-down to icon BMP, masked with the icon mask */
+ if ( SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch) ) {
+ SDL_stack_free(icon_win32);
+ SDL_FreeSurface(icon_256);
+ SDL_SetError("Warning: Unexpected icon_256 characteristics");
+ return;
+ }
+ pdata = (Uint8 *)icon_256->pixels;
+ mdata = mask;
+ pwin32 = (Uint8 *)icon_win32+sizeof(*icon_win32)+icon_plen-icon_pitch;
+ skip = icon_pitch - icon->w;
+ for ( row=0; row<icon->h; ++row ) {
+ for ( col=0; col<icon->w; ++col ) {
+ if ( (col%8) == 0 ) {
+ m = *mdata++;
+ }
+ if ( (m&0x80) != 0x00 ) {
+ *pwin32 = *pdata;
+ }
+ m <<= 1;
+ ++pdata;
+ ++pwin32;
+ }
+ pdata += skip;
+ pwin32 += skip;
+ pwin32 -= 2*icon_pitch;
+ }
+ SDL_FreeSurface(icon_256);
+
+ /* Copy mask inverted and upside-down to icon BMP */
+ mdata = mask;
+ mwin32 = (Uint8 *)icon_win32
+ +sizeof(*icon_win32)+icon_plen+icon_mlen-mask_pitch;
+ for ( row=0; row<icon->h; ++row ) {
+ for ( col=0; col<mask_pitch; ++col ) {
+ *mwin32++ = ~*mdata++;
+ }
+ mwin32 -= 2*mask_pitch;
+ }
+
+ /* Finally, create the icon handle and set the window icon */
+ screen_icn = CreateIconFromResourceEx((Uint8 *)icon_win32, icon_len,
+ TRUE, 0x00030000, icon->w, icon->h, LR_DEFAULTCOLOR);
+ if ( screen_icn == NULL ) {
+ SDL_SetError("Couldn't create Win32 icon handle");
+ } else {
+ SetClassLongPtr(SDL_Window, GCLP_HICON, (LONG_PTR)screen_icn);
+ }
+ SDL_stack_free(icon_win32);
+#endif /* DISABLE_ICON_SUPPORT */
+}
+
+typedef BOOL (WINAPI *PtrSetWindowTextW)(HWND hWnd, LPCWSTR lpString);
+
+void WIN_SetWMCaption(_THIS, const char *title, const char *icon)
+{
+#ifdef _WIN32_WCE
+ /* WinCE uses the UNICODE version */
+ LPWSTR lpszW = SDL_iconv_utf8_ucs2((char *)title);
+ SetWindowText(SDL_Window, lpszW);
+ SDL_free(lpszW);
+#else
+ Uint16 *lpsz = SDL_iconv_utf8_ucs2(title);
+ size_t len = WideCharToMultiByte(CP_ACP, 0, lpsz, -1, NULL, 0, NULL, NULL);
+ char *cvt = SDL_stack_alloc(char, len + 1);
+ WideCharToMultiByte(CP_ACP, 0, lpsz, -1, cvt, len, NULL, NULL);
+ SetWindowText(SDL_Window, cvt);
+ SDL_stack_free(cvt);
+ SDL_free(lpsz);
+#endif
+}
+
+int WIN_IconifyWindow(_THIS)
+{
+ ShowWindow(SDL_Window, SW_MINIMIZE);
+ return(1);
+}
+
+SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ if ( mode == SDL_GRAB_OFF ) {
+ ClipCursor(NULL);
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
+ /* RJR: March 28, 2000
+ must be leaving relative mode, move mouse from
+ center of window to where it belongs ... */
+ POINT pt;
+ int x, y;
+ SDL_GetMouseState(&x,&y);
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(SDL_Window, &pt);
+ SetCursorPos(pt.x,pt.y);
+ }
+#ifdef _WIN32_WCE
+ AllKeys(0);
+#endif
+ } else {
+ ClipCursor(&SDL_bounds);
+ if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) {
+ /* RJR: March 28, 2000
+ must be entering relative mode, get ready by
+ moving mouse to center of window ... */
+ POINT pt;
+ pt.x = (SDL_VideoSurface->w/2);
+ pt.y = (SDL_VideoSurface->h/2);
+ ClientToScreen(SDL_Window, &pt);
+ SetCursorPos(pt.x, pt.y);
+ }
+#ifdef _WIN32_WCE
+ AllKeys(1);
+#endif
+ }
+ return(mode);
+}
+
+/* If 'info' is the right version, this function fills it and returns 1.
+ Otherwise, in case of a version mismatch, it returns -1.
+*/
+int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info)
+{
+ if ( info->version.major <= SDL_MAJOR_VERSION ) {
+ info->window = SDL_Window;
+ if ( SDL_VERSIONNUM(info->version.major,
+ info->version.minor,
+ info->version.patch) >=
+ SDL_VERSIONNUM(1, 2, 5) ) {
+#if SDL_VIDEO_OPENGL
+ info->hglrc = GL_hrc;
+#else
+ info->hglrc = NULL;
+#endif
+ }
+ return(1);
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return(-1);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm_c.h b/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm_c.h
new file mode 100644
index 0000000..a103b43
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_syswm_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_lowvideo.h"
+
+/* Data that needs to be freed at SDL_SYS_VideoQuit() */
+extern HICON screen_icn;
+
+/* Functions to be exported */
+extern void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask);
+extern void WIN_SetWMCaption(_THIS, const char *title, const char *icon);
+extern int WIN_IconifyWindow(_THIS);
+extern SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode);
+extern int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info);
+
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl.c b/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl.c
new file mode 100644
index 0000000..fc4e984
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl.c
@@ -0,0 +1,659 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* WGL implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif
+#include "SDL_lowvideo.h"
+#include "SDL_wingl_c.h"
+
+#if SDL_VIDEO_OPENGL
+#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
+#endif
+
+/* If setting the HDC fails, we may need to recreate the window (MSDN) */
+static int WIN_GL_ResetWindow(_THIS)
+{
+ int status = 0;
+
+#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
+ /* This doesn't work with DirectX code (see CVS comments) */
+ /* If we were passed a window, then we can't create a new one */
+ if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) {
+ /* Save the existing window attributes */
+ LONG style;
+ RECT rect = { 0, 0, 0, 0 };
+ style = GetWindowLong(SDL_Window, GWL_STYLE);
+ GetWindowRect(SDL_Window, &rect);
+ DestroyWindow(SDL_Window);
+ WIN_FlushMessageQueue();
+
+ SDL_resizing = 1;
+ SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
+ style,
+ rect.left, rect.top,
+ (rect.right-rect.left)+1,
+ (rect.bottom-rect.top)+1,
+ NULL, NULL, SDL_Instance, NULL);
+ WIN_FlushMessageQueue();
+ SDL_resizing = 0;
+
+ if ( SDL_Window ) {
+ this->SetCaption(this, this->wm_title, this->wm_icon);
+ } else {
+ SDL_SetError("Couldn't create window");
+ status = -1;
+ }
+ } else
+#endif /* !_WIN32_WCE */
+ {
+ SDL_SetError("Unable to reset window for OpenGL context");
+ status = -1;
+ }
+ return(status);
+}
+
+#if SDL_VIDEO_OPENGL
+
+static int ExtensionSupported(const char *extension, const char *extensions)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if ( where || *extension == '\0' )
+ return 0;
+
+ if ( ! extensions )
+ return 0;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc. */
+
+ start = extensions;
+
+ for (;;)
+ {
+ where = SDL_strstr(start, extension);
+ if (!where) break;
+
+ terminator = where + SDL_strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0') return 1;
+
+ start = terminator;
+ }
+
+ return 0;
+}
+
+static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs)
+{
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+ const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0;
+ const char *extensions;
+ int pformat = 0;
+ UINT matches = 0;
+
+ hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
+ 0, 0, 10, 10,
+ NULL, NULL, SDL_Instance, NULL);
+ WIN_FlushMessageQueue();
+
+ hdc = GetDC(hwnd);
+
+ SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd);
+
+ hglrc = this->gl_data->wglCreateContext(hdc);
+ if ( hglrc ) {
+ this->gl_data->wglMakeCurrent(hdc, hglrc);
+ }
+
+ wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC))
+ this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
+
+ if( wglGetExtensionsStringARB ) {
+ extensions = wglGetExtensionsStringARB(hdc);
+ } else {
+ extensions = NULL;
+ }
+
+ this->gl_data->WGL_ARB_pixel_format = 0;
+ if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) {
+ BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+ wglChoosePixelFormatARB =
+ (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
+ this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
+ if( wglChoosePixelFormatARB &&
+ wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) {
+ this->gl_data->WGL_ARB_pixel_format = 1;
+ }
+ }
+
+ if ( hglrc ) {
+ this->gl_data->wglMakeCurrent(NULL, NULL);
+ this->gl_data->wglDeleteContext(hglrc);
+ }
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ WIN_FlushMessageQueue();
+
+ return pformat;
+}
+
+#endif /* SDL_VIDEO_OPENGL */
+
+int WIN_GL_SetupWindow(_THIS)
+{
+ int retval;
+#if SDL_VIDEO_OPENGL
+ int i;
+ int iAttribs[64];
+ int *iAttr;
+ int *iAccelAttr = NULL;
+ float fAttribs[1] = { 0 };
+ const GLubyte *(WINAPI *glGetStringFunc)(GLenum);
+ const char *wglext;
+
+ /* load the gl driver from a default path */
+ if ( ! this->gl_config.driver_loaded ) {
+ /* no driver has been loaded, use default (ourselves) */
+ if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
+ return(-1);
+ }
+ }
+
+ /* Set up the pixel format descriptor with our needed format */
+ SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
+ GL_pfd.nSize = sizeof(GL_pfd);
+ GL_pfd.nVersion = 1;
+ GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
+ if ( this->gl_config.double_buffer ) {
+ GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ }
+ if ( this->gl_config.stereo ) {
+ GL_pfd.dwFlags |= PFD_STEREO;
+ }
+ GL_pfd.iPixelType = PFD_TYPE_RGBA;
+ GL_pfd.cColorBits = this->gl_config.buffer_size;
+ GL_pfd.cRedBits = this->gl_config.red_size;
+ GL_pfd.cGreenBits = this->gl_config.green_size;
+ GL_pfd.cBlueBits = this->gl_config.blue_size;
+ GL_pfd.cAlphaBits = this->gl_config.alpha_size;
+ GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
+ GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
+ GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
+ GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
+ GL_pfd.cAccumBits =
+ (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
+ GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
+ GL_pfd.cDepthBits = this->gl_config.depth_size;
+ GL_pfd.cStencilBits = this->gl_config.stencil_size;
+
+ /* setup WGL_ARB_pixel_format attribs */
+ iAttr = &iAttribs[0];
+
+ *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
+ *iAttr++ = GL_TRUE;
+ *iAttr++ = WGL_RED_BITS_ARB;
+ *iAttr++ = this->gl_config.red_size;
+ *iAttr++ = WGL_GREEN_BITS_ARB;
+ *iAttr++ = this->gl_config.green_size;
+ *iAttr++ = WGL_BLUE_BITS_ARB;
+ *iAttr++ = this->gl_config.blue_size;
+
+ /* We always choose either FULL or NO accel on Windows, because of flaky
+ drivers. If the app didn't specify, we use FULL, because that's
+ probably what they wanted (and if you didn't care and got FULL, that's
+ a perfectly valid result in any case. */
+ *iAttr++ = WGL_ACCELERATION_ARB;
+ iAccelAttr = iAttr;
+ if (this->gl_config.accelerated) {
+ *iAttr++ = WGL_FULL_ACCELERATION_ARB;
+ } else {
+ *iAttr++ = WGL_NO_ACCELERATION_ARB;
+ }
+
+ if ( this->gl_config.alpha_size ) {
+ *iAttr++ = WGL_ALPHA_BITS_ARB;
+ *iAttr++ = this->gl_config.alpha_size;
+ }
+
+ *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
+ *iAttr++ = this->gl_config.double_buffer;
+
+ *iAttr++ = WGL_DEPTH_BITS_ARB;
+ *iAttr++ = this->gl_config.depth_size;
+
+ if ( this->gl_config.stencil_size ) {
+ *iAttr++ = WGL_STENCIL_BITS_ARB;
+ *iAttr++ = this->gl_config.stencil_size;
+ }
+
+ if ( this->gl_config.accum_red_size ) {
+ *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
+ *iAttr++ = this->gl_config.accum_red_size;
+ }
+
+ if ( this->gl_config.accum_green_size ) {
+ *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
+ *iAttr++ = this->gl_config.accum_green_size;
+ }
+
+ if ( this->gl_config.accum_blue_size ) {
+ *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
+ *iAttr++ = this->gl_config.accum_blue_size;
+ }
+
+ if ( this->gl_config.accum_alpha_size ) {
+ *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
+ *iAttr++ = this->gl_config.accum_alpha_size;
+ }
+
+ if ( this->gl_config.stereo ) {
+ *iAttr++ = WGL_STEREO_ARB;
+ *iAttr++ = GL_TRUE;
+ }
+
+ if ( this->gl_config.multisamplebuffers ) {
+ *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
+ *iAttr++ = this->gl_config.multisamplebuffers;
+ }
+
+ if ( this->gl_config.multisamplesamples ) {
+ *iAttr++ = WGL_SAMPLES_ARB;
+ *iAttr++ = this->gl_config.multisamplesamples;
+ }
+
+ *iAttr = 0;
+
+ for ( i=0; ; ++i ) {
+ /* Get the window device context for our OpenGL drawing */
+ GL_hdc = GetDC(SDL_Window);
+ if ( GL_hdc == NULL ) {
+ SDL_SetError("Unable to get DC for SDL_Window");
+ return(-1);
+ }
+
+ /* Choose and set the closest available pixel format */
+ pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
+ /* App said "don't care about accel" and FULL accel failed. Try NO. */
+ if ( ( !pixel_format ) && ( this->gl_config.accelerated < 0 ) ) {
+ *iAccelAttr = WGL_NO_ACCELERATION_ARB;
+ pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
+ *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
+ }
+ if ( !pixel_format ) {
+ pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
+ }
+ if ( !pixel_format ) {
+ SDL_SetError("No matching GL pixel format available");
+ return(-1);
+ }
+ if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
+ if ( i == 0 ) {
+ /* First time through, try resetting the window */
+ if ( WIN_GL_ResetWindow(this) < 0 ) {
+ return(-1);
+ }
+ continue;
+ }
+ SDL_SetError("Unable to set HDC pixel format");
+ return(-1);
+ }
+ /* We either succeeded or failed by this point */
+ break;
+ }
+ DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
+
+ GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
+ if ( GL_hrc == NULL ) {
+ SDL_SetError("Unable to create GL context");
+ return(-1);
+ }
+ if ( WIN_GL_MakeCurrent(this) < 0 ) {
+ return(-1);
+ }
+ gl_active = 1;
+
+ /* Get the wglGetPixelFormatAttribivARB pointer for the context */
+ if ( this->gl_data->WGL_ARB_pixel_format ) {
+ this->gl_data->wglGetPixelFormatAttribivARB =
+ (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
+ this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
+ } else {
+ this->gl_data->wglGetPixelFormatAttribivARB = NULL;
+ }
+
+ /* Vsync control under Windows. Checking glGetString here is
+ * somewhat a documented and reliable hack - it was originally
+ * as a feature added by mistake, but since so many people rely
+ * on it, it will not be removed. strstr should be safe here.*/
+ glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
+ if ( glGetStringFunc ) {
+ wglext = (const char *)glGetStringFunc(GL_EXTENSIONS);
+ } else {
+ /* Uh oh, something is seriously wrong here... */
+ wglext = NULL;
+ }
+ if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) {
+ this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
+ this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
+ } else {
+ this->gl_data->wglSwapIntervalEXT = NULL;
+ this->gl_data->wglGetSwapIntervalEXT = NULL;
+ }
+ if ( this->gl_config.swap_control >= 0 ) {
+ if ( this->gl_data->wglSwapIntervalEXT ) {
+ this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
+ }
+ }
+#else
+ SDL_SetError("WIN driver not configured with OpenGL");
+#endif
+ if ( gl_active ) {
+ retval = 0;
+ } else {
+ retval = -1;
+ }
+ return(retval);
+}
+
+void WIN_GL_ShutDown(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+ /* Clean up OpenGL */
+ if ( GL_hrc ) {
+ this->gl_data->wglMakeCurrent(NULL, NULL);
+ this->gl_data->wglDeleteContext(GL_hrc);
+ GL_hrc = NULL;
+ }
+ if ( GL_hdc ) {
+ ReleaseDC(SDL_Window, GL_hdc);
+ GL_hdc = NULL;
+ }
+ gl_active = 0;
+
+ WIN_GL_UnloadLibrary(this);
+#endif /* SDL_VIDEO_OPENGL */
+}
+
+#if SDL_VIDEO_OPENGL
+
+/* Make the current context active */
+int WIN_GL_MakeCurrent(_THIS)
+{
+ int retval;
+
+ retval = 0;
+ if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) {
+ SDL_SetError("Unable to make GL context current");
+ retval = -1;
+ }
+ return(retval);
+}
+
+/* Get attribute data from wgl. */
+int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ int retval;
+
+ if (attrib == SDL_GL_SWAP_CONTROL) {
+ if ( this->gl_data->wglGetSwapIntervalEXT ) {
+ *value = this->gl_data->wglGetSwapIntervalEXT();
+ return 0;
+ }
+ return -1;
+ }
+
+ if ( this->gl_data->wglGetPixelFormatAttribivARB ) {
+ int wgl_attrib;
+
+ switch(attrib) {
+ case SDL_GL_RED_SIZE:
+ wgl_attrib = WGL_RED_BITS_ARB;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ wgl_attrib = WGL_GREEN_BITS_ARB;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ wgl_attrib = WGL_BLUE_BITS_ARB;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ wgl_attrib = WGL_ALPHA_BITS_ARB;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ wgl_attrib = WGL_COLOR_BITS_ARB;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ wgl_attrib = WGL_DEPTH_BITS_ARB;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ wgl_attrib = WGL_STENCIL_BITS_ARB;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
+ break;
+ case SDL_GL_STEREO:
+ wgl_attrib = WGL_STEREO_ARB;
+ break;
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ wgl_attrib = WGL_SAMPLES_ARB;
+ break;
+ case SDL_GL_ACCELERATED_VISUAL:
+ wgl_attrib = WGL_ACCELERATION_ARB;
+ this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
+ if ( *value == WGL_NO_ACCELERATION_ARB ) {
+ *value = SDL_FALSE;
+ } else {
+ *value = SDL_TRUE;
+ }
+ return 0;
+ default:
+ return(-1);
+ }
+ this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
+
+ return 0;
+ }
+
+ retval = 0;
+ switch ( attrib ) {
+ case SDL_GL_RED_SIZE:
+ *value = GL_pfd.cRedBits;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ *value = GL_pfd.cGreenBits;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ *value = GL_pfd.cBlueBits;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ *value = GL_pfd.cAlphaBits;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) {
+ *value = 1;
+ } else {
+ *value = 0;
+ }
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ *value = GL_pfd.cColorBits;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ *value = GL_pfd.cDepthBits;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ *value = GL_pfd.cStencilBits;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ *value = GL_pfd.cAccumRedBits;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ *value = GL_pfd.cAccumGreenBits;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ *value = GL_pfd.cAccumBlueBits;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ *value = GL_pfd.cAccumAlphaBits;
+ break;
+ case SDL_GL_STEREO:
+ if ( GL_pfd.dwFlags & PFD_STEREO ) {
+ *value = 1;
+ } else {
+ *value = 0;
+ }
+ break;
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ *value = 0;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ *value = 1;
+ break;
+ case SDL_GL_SWAP_CONTROL:
+ if ( this->gl_data->wglGetSwapIntervalEXT ) {
+ *value = this->gl_data->wglGetSwapIntervalEXT();
+ return 0;
+ } else {
+ return -1;
+ }
+ break;
+ default:
+ retval = -1;
+ break;
+ }
+ return retval;
+}
+
+void WIN_GL_SwapBuffers(_THIS)
+{
+ SwapBuffers(GL_hdc);
+}
+
+void WIN_GL_UnloadLibrary(_THIS)
+{
+ if ( this->gl_config.driver_loaded ) {
+ FreeLibrary((HMODULE)this->gl_config.dll_handle);
+
+ this->gl_data->wglGetProcAddress = NULL;
+ this->gl_data->wglCreateContext = NULL;
+ this->gl_data->wglDeleteContext = NULL;
+ this->gl_data->wglMakeCurrent = NULL;
+ this->gl_data->wglGetPixelFormatAttribivARB = NULL;
+ this->gl_data->wglSwapIntervalEXT = NULL;
+ this->gl_data->wglGetSwapIntervalEXT = NULL;
+
+ this->gl_config.dll_handle = NULL;
+ this->gl_config.driver_loaded = 0;
+ }
+}
+
+/* Passing a NULL path means load pointers from the application */
+int WIN_GL_LoadLibrary(_THIS, const char* path)
+{
+ HMODULE handle;
+
+ if ( gl_active ) {
+ SDL_SetError("OpenGL context already created");
+ return -1;
+ }
+
+ if ( path == NULL ) {
+ path = DEFAULT_GL_DRIVER_PATH;
+ }
+ handle = LoadLibrary(path);
+ if ( handle == NULL ) {
+ SDL_SetError("Could not load OpenGL library");
+ return -1;
+ }
+
+ /* Unload the old driver and reset the pointers */
+ WIN_GL_UnloadLibrary(this);
+
+ /* Load new function pointers */
+ SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
+ this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
+ GetProcAddress(handle, "wglGetProcAddress");
+ this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
+ GetProcAddress(handle, "wglCreateContext");
+ this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC))
+ GetProcAddress(handle, "wglDeleteContext");
+ this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
+ GetProcAddress(handle, "wglMakeCurrent");
+ this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int))
+ GetProcAddress(handle, "wglSwapIntervalEXT");
+ this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void))
+ GetProcAddress(handle, "wglGetSwapIntervalEXT");
+
+ if ( (this->gl_data->wglGetProcAddress == NULL) ||
+ (this->gl_data->wglCreateContext == NULL) ||
+ (this->gl_data->wglDeleteContext == NULL) ||
+ (this->gl_data->wglMakeCurrent == NULL) ) {
+ SDL_SetError("Could not retrieve OpenGL functions");
+ FreeLibrary(handle);
+ return -1;
+ }
+
+ this->gl_config.dll_handle = handle;
+ SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path));
+ this->gl_config.driver_loaded = 1;
+ return 0;
+}
+
+void *WIN_GL_GetProcAddress(_THIS, const char* proc)
+{
+ void *func;
+
+ /* This is to pick up extensions */
+ func = this->gl_data->wglGetProcAddress(proc);
+ if ( ! func ) {
+ /* This is probably a normal GL function */
+ func = GetProcAddress(this->gl_config.dll_handle, proc);
+ }
+ return func;
+}
+
+#endif /* SDL_VIDEO_OPENGL */
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl_c.h b/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl_c.h
new file mode 100644
index 0000000..c3f2291
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/SDL_wingl_c.h
@@ -0,0 +1,135 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* WGL implementation of SDL OpenGL support */
+
+#include "../SDL_sysvideo.h"
+
+
+struct SDL_PrivateGLData {
+ int gl_active; /* to stop switching drivers while we have a valid context */
+
+#if SDL_VIDEO_OPENGL
+ PIXELFORMATDESCRIPTOR GL_pfd;
+ HDC GL_hdc;
+ HGLRC GL_hrc;
+ int pixel_format;
+ int WGL_ARB_pixel_format;
+
+ void * (WINAPI *wglGetProcAddress)(const char *proc);
+
+ HGLRC (WINAPI *wglCreateContext)(HDC hdc);
+
+ BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc);
+
+ BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc);
+
+ BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat,
+ int iLayerPlane,
+ UINT nAttributes,
+ const int *piAttributes,
+ int *piValues);
+ void (WINAPI *wglSwapIntervalEXT)(int interval);
+ int (WINAPI *wglGetSwapIntervalEXT)(void);
+#endif /* SDL_VIDEO_OPENGL */
+};
+
+/* Old variable names */
+#define gl_active (this->gl_data->gl_active)
+#define GL_pfd (this->gl_data->GL_pfd)
+#define GL_hdc (this->gl_data->GL_hdc)
+#define GL_hrc (this->gl_data->GL_hrc)
+#define pixel_format (this->gl_data->pixel_format)
+
+/* OpenGL functions */
+extern int WIN_GL_SetupWindow(_THIS);
+extern void WIN_GL_ShutDown(_THIS);
+#if SDL_VIDEO_OPENGL
+extern int WIN_GL_MakeCurrent(_THIS);
+extern int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+extern void WIN_GL_SwapBuffers(_THIS);
+extern void WIN_GL_UnloadLibrary(_THIS);
+extern int WIN_GL_LoadLibrary(_THIS, const char* path);
+extern void *WIN_GL_GetProcAddress(_THIS, const char* proc);
+#endif
+
+#if SDL_VIDEO_OPENGL
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/wincommon/wmmsg.h b/distrib/sdl-1.2.15/src/video/wincommon/wmmsg.h
new file mode 100644
index 0000000..175a8ce
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wincommon/wmmsg.h
@@ -0,0 +1,1030 @@
+
+#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0]))
+
+char *wmtab[] = {
+ "WM_NULL",
+ "WM_CREATE",
+ "WM_DESTROY",
+ "WM_MOVE",
+ "UNKNOWN (4)",
+ "WM_SIZE",
+ "WM_ACTIVATE",
+ "WM_SETFOCUS",
+ "WM_KILLFOCUS",
+ "UNKNOWN (9)",
+ "WM_ENABLE",
+ "WM_SETREDRAW",
+ "WM_SETTEXT",
+ "WM_GETTEXT",
+ "WM_GETTEXTLENGTH",
+ "WM_PAINT",
+ "WM_CLOSE",
+ "WM_QUERYENDSESSION",
+ "WM_QUIT",
+ "WM_QUERYOPEN",
+ "WM_ERASEBKGND",
+ "WM_SYSCOLORCHANGE",
+ "WM_ENDSESSION",
+ "UNKNOWN (23)",
+ "WM_SHOWWINDOW",
+ "UNKNOWN (25)",
+ "WM_SETTINGCHANGE",
+ "WM_DEVMODECHANGE",
+ "WM_ACTIVATEAPP",
+ "WM_FONTCHANGE",
+ "WM_TIMECHANGE",
+ "WM_CANCELMODE",
+ "WM_SETCURSOR",
+ "WM_MOUSEACTIVATE",
+ "WM_CHILDACTIVATE",
+ "WM_QUEUESYNC",
+ "WM_GETMINMAXINFO",
+ "UNKNOWN (37)",
+ "WM_PAINTICON",
+ "WM_ICONERASEBKGND",
+ "WM_NEXTDLGCTL",
+ "UNKNOWN (41)",
+ "WM_SPOOLERSTATUS",
+ "WM_DRAWITEM",
+ "WM_MEASUREITEM",
+ "WM_DELETEITEM",
+ "WM_VKEYTOITEM",
+ "WM_CHARTOITEM",
+ "WM_SETFONT",
+ "WM_GETFONT",
+ "WM_SETHOTKEY",
+ "WM_GETHOTKEY",
+ "UNKNOWN (52)",
+ "UNKNOWN (53)",
+ "UNKNOWN (54)",
+ "WM_QUERYDRAGICON",
+ "UNKNOWN (56)",
+ "WM_COMPAREITEM",
+ "UNKNOWN (58)",
+ "UNKNOWN (59)",
+ "UNKNOWN (60)",
+ "WM_GETOBJECT",
+ "UNKNOWN (62)",
+ "UNKNOWN (63)",
+ "UNKNOWN (64)",
+ "WM_COMPACTING",
+ "UNKNOWN (66)",
+ "UNKNOWN (67)",
+ "WM_COMMNOTIFY",
+ "UNKNOWN (69)",
+ "WM_WINDOWPOSCHANGING",
+ "WM_WINDOWPOSCHANGED",
+ "WM_POWER",
+ "UNKNOWN (73)",
+ "WM_COPYDATA",
+ "WM_CANCELJOURNAL",
+ "UNKNOWN (76)",
+ "UNKNOWN (77)",
+ "WM_NOTIFY",
+ "UNKNOWN (79)",
+ "WM_INPUTLANGCHANGEREQUEST",
+ "WM_INPUTLANGCHANGE",
+ "WM_TCARD",
+ "WM_HELP",
+ "WM_USERCHANGED",
+ "WM_NOTIFYFORMAT",
+ "UNKNOWN (86)",
+ "UNKNOWN (87)",
+ "UNKNOWN (88)",
+ "UNKNOWN (89)",
+ "UNKNOWN (90)",
+ "UNKNOWN (91)",
+ "UNKNOWN (92)",
+ "UNKNOWN (93)",
+ "UNKNOWN (94)",
+ "UNKNOWN (95)",
+ "UNKNOWN (96)",
+ "UNKNOWN (97)",
+ "UNKNOWN (98)",
+ "UNKNOWN (99)",
+ "UNKNOWN (100)",
+ "UNKNOWN (101)",
+ "UNKNOWN (102)",
+ "UNKNOWN (103)",
+ "UNKNOWN (104)",
+ "UNKNOWN (105)",
+ "UNKNOWN (106)",
+ "UNKNOWN (107)",
+ "UNKNOWN (108)",
+ "UNKNOWN (109)",
+ "UNKNOWN (110)",
+ "UNKNOWN (111)",
+ "UNKNOWN (112)",
+ "UNKNOWN (113)",
+ "UNKNOWN (114)",
+ "UNKNOWN (115)",
+ "UNKNOWN (116)",
+ "UNKNOWN (117)",
+ "UNKNOWN (118)",
+ "UNKNOWN (119)",
+ "UNKNOWN (120)",
+ "UNKNOWN (121)",
+ "UNKNOWN (122)",
+ "WM_CONTEXTMENU",
+ "WM_STYLECHANGING",
+ "WM_STYLECHANGED",
+ "WM_DISPLAYCHANGE",
+ "WM_GETICON",
+ "WM_SETICON",
+ "WM_NCCREATE",
+ "WM_NCDESTROY",
+ "WM_NCCALCSIZE",
+ "WM_NCHITTEST",
+ "WM_NCPAINT",
+ "WM_NCACTIVATE",
+ "WM_GETDLGCODE",
+ "WM_SYNCPAINT",
+ "UNKNOWN (137)",
+ "UNKNOWN (138)",
+ "UNKNOWN (139)",
+ "UNKNOWN (140)",
+ "UNKNOWN (141)",
+ "UNKNOWN (142)",
+ "UNKNOWN (143)",
+ "UNKNOWN (144)",
+ "UNKNOWN (145)",
+ "UNKNOWN (146)",
+ "UNKNOWN (147)",
+ "UNKNOWN (148)",
+ "UNKNOWN (149)",
+ "UNKNOWN (150)",
+ "UNKNOWN (151)",
+ "UNKNOWN (152)",
+ "UNKNOWN (153)",
+ "UNKNOWN (154)",
+ "UNKNOWN (155)",
+ "UNKNOWN (156)",
+ "UNKNOWN (157)",
+ "UNKNOWN (158)",
+ "UNKNOWN (159)",
+ "WM_NCMOUSEMOVE",
+ "WM_NCLBUTTONDOWN",
+ "WM_NCLBUTTONUP",
+ "WM_NCLBUTTONDBLCLK",
+ "WM_NCRBUTTONDOWN",
+ "WM_NCRBUTTONUP",
+ "WM_NCRBUTTONDBLCLK",
+ "WM_NCMBUTTONDOWN",
+ "WM_NCMBUTTONUP",
+ "WM_NCMBUTTONDBLCLK",
+ "UNKNOWN (170)",
+ "UNKNOWN (171)",
+ "UNKNOWN (172)",
+ "UNKNOWN (173)",
+ "UNKNOWN (174)",
+ "UNKNOWN (175)",
+ "UNKNOWN (176)",
+ "UNKNOWN (177)",
+ "UNKNOWN (178)",
+ "UNKNOWN (179)",
+ "UNKNOWN (180)",
+ "UNKNOWN (181)",
+ "UNKNOWN (182)",
+ "UNKNOWN (183)",
+ "UNKNOWN (184)",
+ "UNKNOWN (185)",
+ "UNKNOWN (186)",
+ "UNKNOWN (187)",
+ "UNKNOWN (188)",
+ "UNKNOWN (189)",
+ "UNKNOWN (190)",
+ "UNKNOWN (191)",
+ "UNKNOWN (192)",
+ "UNKNOWN (193)",
+ "UNKNOWN (194)",
+ "UNKNOWN (195)",
+ "UNKNOWN (196)",
+ "UNKNOWN (197)",
+ "UNKNOWN (198)",
+ "UNKNOWN (199)",
+ "UNKNOWN (200)",
+ "UNKNOWN (201)",
+ "UNKNOWN (202)",
+ "UNKNOWN (203)",
+ "UNKNOWN (204)",
+ "UNKNOWN (205)",
+ "UNKNOWN (206)",
+ "UNKNOWN (207)",
+ "UNKNOWN (208)",
+ "UNKNOWN (209)",
+ "UNKNOWN (210)",
+ "UNKNOWN (211)",
+ "UNKNOWN (212)",
+ "UNKNOWN (213)",
+ "UNKNOWN (214)",
+ "UNKNOWN (215)",
+ "UNKNOWN (216)",
+ "UNKNOWN (217)",
+ "UNKNOWN (218)",
+ "UNKNOWN (219)",
+ "UNKNOWN (220)",
+ "UNKNOWN (221)",
+ "UNKNOWN (222)",
+ "UNKNOWN (223)",
+ "UNKNOWN (224)",
+ "UNKNOWN (225)",
+ "UNKNOWN (226)",
+ "UNKNOWN (227)",
+ "UNKNOWN (228)",
+ "UNKNOWN (229)",
+ "UNKNOWN (230)",
+ "UNKNOWN (231)",
+ "UNKNOWN (232)",
+ "UNKNOWN (233)",
+ "UNKNOWN (234)",
+ "UNKNOWN (235)",
+ "UNKNOWN (236)",
+ "UNKNOWN (237)",
+ "UNKNOWN (238)",
+ "UNKNOWN (239)",
+ "UNKNOWN (240)",
+ "UNKNOWN (241)",
+ "UNKNOWN (242)",
+ "UNKNOWN (243)",
+ "UNKNOWN (244)",
+ "UNKNOWN (245)",
+ "UNKNOWN (246)",
+ "UNKNOWN (247)",
+ "UNKNOWN (248)",
+ "UNKNOWN (249)",
+ "UNKNOWN (250)",
+ "UNKNOWN (251)",
+ "UNKNOWN (252)",
+ "UNKNOWN (253)",
+ "UNKNOWN (254)",
+ "UNKNOWN (255)",
+ "WM_KEYDOWN",
+ "WM_KEYUP",
+ "WM_CHAR",
+ "WM_DEADCHAR",
+ "WM_SYSKEYDOWN",
+ "WM_SYSKEYUP",
+ "WM_SYSCHAR",
+ "WM_SYSDEADCHAR",
+ "WM_KEYLAST",
+ "UNKNOWN (265)",
+ "UNKNOWN (266)",
+ "UNKNOWN (267)",
+ "UNKNOWN (268)",
+ "UNKNOWN (269)",
+ "UNKNOWN (270)",
+ "UNKNOWN (271)",
+ "WM_INITDIALOG",
+ "WM_COMMAND",
+ "WM_SYSCOMMAND",
+ "WM_TIMER",
+ "WM_HSCROLL",
+ "WM_VSCROLL",
+ "WM_INITMENU",
+ "WM_INITMENUPOPUP",
+ "UNKNOWN (280)",
+ "UNKNOWN (281)",
+ "UNKNOWN (282)",
+ "UNKNOWN (283)",
+ "UNKNOWN (284)",
+ "UNKNOWN (285)",
+ "UNKNOWN (286)",
+ "WM_MENUSELECT",
+ "WM_MENUCHAR",
+ "WM_ENTERIDLE",
+ "WM_MENURBUTTONUP",
+ "WM_MENUDRAG",
+ "WM_MENUGETOBJECT",
+ "WM_UNINITMENUPOPUP",
+ "WM_MENUCOMMAND",
+ "UNKNOWN (295)",
+ "UNKNOWN (296)",
+ "UNKNOWN (297)",
+ "UNKNOWN (298)",
+ "UNKNOWN (299)",
+ "UNKNOWN (300)",
+ "UNKNOWN (301)",
+ "UNKNOWN (302)",
+ "UNKNOWN (303)",
+ "UNKNOWN (304)",
+ "UNKNOWN (305)",
+ "WM_CTLCOLORMSGBOX",
+ "WM_CTLCOLOREDIT",
+ "WM_CTLCOLORLISTBOX",
+ "WM_CTLCOLORBTN",
+ "WM_CTLCOLORDLG",
+ "WM_CTLCOLORSCROLLBAR",
+ "WM_CTLCOLORSTATIC",
+ "UNKNOWN (313)",
+ "UNKNOWN (314)",
+ "UNKNOWN (315)",
+ "UNKNOWN (316)",
+ "UNKNOWN (317)",
+ "UNKNOWN (318)",
+ "UNKNOWN (319)",
+ "UNKNOWN (320)",
+ "UNKNOWN (321)",
+ "UNKNOWN (322)",
+ "UNKNOWN (323)",
+ "UNKNOWN (324)",
+ "UNKNOWN (325)",
+ "UNKNOWN (326)",
+ "UNKNOWN (327)",
+ "UNKNOWN (328)",
+ "UNKNOWN (329)",
+ "UNKNOWN (330)",
+ "UNKNOWN (331)",
+ "UNKNOWN (332)",
+ "UNKNOWN (333)",
+ "UNKNOWN (334)",
+ "UNKNOWN (335)",
+ "UNKNOWN (336)",
+ "UNKNOWN (337)",
+ "UNKNOWN (338)",
+ "UNKNOWN (339)",
+ "UNKNOWN (340)",
+ "UNKNOWN (341)",
+ "UNKNOWN (342)",
+ "UNKNOWN (343)",
+ "UNKNOWN (344)",
+ "UNKNOWN (345)",
+ "UNKNOWN (346)",
+ "UNKNOWN (347)",
+ "UNKNOWN (348)",
+ "UNKNOWN (349)",
+ "UNKNOWN (350)",
+ "UNKNOWN (351)",
+ "UNKNOWN (352)",
+ "UNKNOWN (353)",
+ "UNKNOWN (354)",
+ "UNKNOWN (355)",
+ "UNKNOWN (356)",
+ "UNKNOWN (357)",
+ "UNKNOWN (358)",
+ "UNKNOWN (359)",
+ "UNKNOWN (360)",
+ "UNKNOWN (361)",
+ "UNKNOWN (362)",
+ "UNKNOWN (363)",
+ "UNKNOWN (364)",
+ "UNKNOWN (365)",
+ "UNKNOWN (366)",
+ "UNKNOWN (367)",
+ "UNKNOWN (368)",
+ "UNKNOWN (369)",
+ "UNKNOWN (370)",
+ "UNKNOWN (371)",
+ "UNKNOWN (372)",
+ "UNKNOWN (373)",
+ "UNKNOWN (374)",
+ "UNKNOWN (375)",
+ "UNKNOWN (376)",
+ "UNKNOWN (377)",
+ "UNKNOWN (378)",
+ "UNKNOWN (379)",
+ "UNKNOWN (380)",
+ "UNKNOWN (381)",
+ "UNKNOWN (382)",
+ "UNKNOWN (383)",
+ "UNKNOWN (384)",
+ "UNKNOWN (385)",
+ "UNKNOWN (386)",
+ "UNKNOWN (387)",
+ "UNKNOWN (388)",
+ "UNKNOWN (389)",
+ "UNKNOWN (390)",
+ "UNKNOWN (391)",
+ "UNKNOWN (392)",
+ "UNKNOWN (393)",
+ "UNKNOWN (394)",
+ "UNKNOWN (395)",
+ "UNKNOWN (396)",
+ "UNKNOWN (397)",
+ "UNKNOWN (398)",
+ "UNKNOWN (399)",
+ "UNKNOWN (400)",
+ "UNKNOWN (401)",
+ "UNKNOWN (402)",
+ "UNKNOWN (403)",
+ "UNKNOWN (404)",
+ "UNKNOWN (405)",
+ "UNKNOWN (406)",
+ "UNKNOWN (407)",
+ "UNKNOWN (408)",
+ "UNKNOWN (409)",
+ "UNKNOWN (410)",
+ "UNKNOWN (411)",
+ "UNKNOWN (412)",
+ "UNKNOWN (413)",
+ "UNKNOWN (414)",
+ "UNKNOWN (415)",
+ "UNKNOWN (416)",
+ "UNKNOWN (417)",
+ "UNKNOWN (418)",
+ "UNKNOWN (419)",
+ "UNKNOWN (420)",
+ "UNKNOWN (421)",
+ "UNKNOWN (422)",
+ "UNKNOWN (423)",
+ "UNKNOWN (424)",
+ "UNKNOWN (425)",
+ "UNKNOWN (426)",
+ "UNKNOWN (427)",
+ "UNKNOWN (428)",
+ "UNKNOWN (429)",
+ "UNKNOWN (430)",
+ "UNKNOWN (431)",
+ "UNKNOWN (432)",
+ "UNKNOWN (433)",
+ "UNKNOWN (434)",
+ "UNKNOWN (435)",
+ "UNKNOWN (436)",
+ "UNKNOWN (437)",
+ "UNKNOWN (438)",
+ "UNKNOWN (439)",
+ "UNKNOWN (440)",
+ "UNKNOWN (441)",
+ "UNKNOWN (442)",
+ "UNKNOWN (443)",
+ "UNKNOWN (444)",
+ "UNKNOWN (445)",
+ "UNKNOWN (446)",
+ "UNKNOWN (447)",
+ "UNKNOWN (448)",
+ "UNKNOWN (449)",
+ "UNKNOWN (450)",
+ "UNKNOWN (451)",
+ "UNKNOWN (452)",
+ "UNKNOWN (453)",
+ "UNKNOWN (454)",
+ "UNKNOWN (455)",
+ "UNKNOWN (456)",
+ "UNKNOWN (457)",
+ "UNKNOWN (458)",
+ "UNKNOWN (459)",
+ "UNKNOWN (460)",
+ "UNKNOWN (461)",
+ "UNKNOWN (462)",
+ "UNKNOWN (463)",
+ "UNKNOWN (464)",
+ "UNKNOWN (465)",
+ "UNKNOWN (466)",
+ "UNKNOWN (467)",
+ "UNKNOWN (468)",
+ "UNKNOWN (469)",
+ "UNKNOWN (470)",
+ "UNKNOWN (471)",
+ "UNKNOWN (472)",
+ "UNKNOWN (473)",
+ "UNKNOWN (474)",
+ "UNKNOWN (475)",
+ "UNKNOWN (476)",
+ "UNKNOWN (477)",
+ "UNKNOWN (478)",
+ "UNKNOWN (479)",
+ "UNKNOWN (480)",
+ "UNKNOWN (481)",
+ "UNKNOWN (482)",
+ "UNKNOWN (483)",
+ "UNKNOWN (484)",
+ "UNKNOWN (485)",
+ "UNKNOWN (486)",
+ "UNKNOWN (487)",
+ "UNKNOWN (488)",
+ "UNKNOWN (489)",
+ "UNKNOWN (490)",
+ "UNKNOWN (491)",
+ "UNKNOWN (492)",
+ "UNKNOWN (493)",
+ "UNKNOWN (494)",
+ "UNKNOWN (495)",
+ "UNKNOWN (496)",
+ "UNKNOWN (497)",
+ "UNKNOWN (498)",
+ "UNKNOWN (499)",
+ "UNKNOWN (500)",
+ "UNKNOWN (501)",
+ "UNKNOWN (502)",
+ "UNKNOWN (503)",
+ "UNKNOWN (504)",
+ "UNKNOWN (505)",
+ "UNKNOWN (506)",
+ "UNKNOWN (507)",
+ "UNKNOWN (508)",
+ "UNKNOWN (509)",
+ "UNKNOWN (510)",
+ "UNKNOWN (511)",
+ "WM_MOUSEMOVE",
+ "WM_LBUTTONDOWN",
+ "WM_LBUTTONUP",
+ "WM_LBUTTONDBLCLK",
+ "WM_RBUTTONDOWN",
+ "WM_RBUTTONUP",
+ "WM_RBUTTONDBLCLK",
+ "WM_MBUTTONDOWN",
+ "WM_MBUTTONUP",
+ "WM_MOUSELAST",
+ "WM_MOUSEWHEEL",
+ "WM_XBUTTONDOWN",
+ "WM_XBUTTONUP",
+ "UNKNOWN (525)",
+ "UNKNOWN (526)",
+ "UNKNOWN (527)",
+ "WM_PARENTNOTIFY",
+ "WM_ENTERMENULOOP",
+ "WM_EXITMENULOOP",
+ "WM_NEXTMENU",
+ "WM_SIZING",
+ "WM_CAPTURECHANGED",
+ "WM_MOVING",
+ "UNKNOWN (535)",
+ "WM_POWERBROADCAST",
+ "WM_DEVICECHANGE",
+ "UNKNOWN (538)",
+ "UNKNOWN (539)",
+ "UNKNOWN (540)",
+ "UNKNOWN (541)",
+ "UNKNOWN (542)",
+ "UNKNOWN (543)",
+ "WM_MDICREATE",
+ "WM_MDIDESTROY",
+ "WM_MDIACTIVATE",
+ "WM_MDIRESTORE",
+ "WM_MDINEXT",
+ "WM_MDIMAXIMIZE",
+ "WM_MDITILE",
+ "WM_MDICASCADE",
+ "WM_MDIICONARRANGE",
+ "WM_MDIGETACTIVE",
+ "UNKNOWN (554)",
+ "UNKNOWN (555)",
+ "UNKNOWN (556)",
+ "UNKNOWN (557)",
+ "UNKNOWN (558)",
+ "UNKNOWN (559)",
+ "WM_MDISETMENU",
+ "WM_ENTERSIZEMOVE",
+ "WM_EXITSIZEMOVE",
+ "WM_DROPFILES",
+ "WM_MDIREFRESHMENU",
+ "UNKNOWN (565)",
+ "UNKNOWN (566)",
+ "UNKNOWN (567)",
+ "UNKNOWN (568)",
+ "UNKNOWN (569)",
+ "UNKNOWN (570)",
+ "UNKNOWN (571)",
+ "UNKNOWN (572)",
+ "UNKNOWN (573)",
+ "UNKNOWN (574)",
+ "UNKNOWN (575)",
+ "UNKNOWN (576)",
+ "UNKNOWN (577)",
+ "UNKNOWN (578)",
+ "UNKNOWN (579)",
+ "UNKNOWN (580)",
+ "UNKNOWN (581)",
+ "UNKNOWN (582)",
+ "UNKNOWN (583)",
+ "UNKNOWN (584)",
+ "UNKNOWN (585)",
+ "UNKNOWN (586)",
+ "UNKNOWN (587)",
+ "UNKNOWN (588)",
+ "UNKNOWN (589)",
+ "UNKNOWN (590)",
+ "UNKNOWN (591)",
+ "UNKNOWN (592)",
+ "UNKNOWN (593)",
+ "UNKNOWN (594)",
+ "UNKNOWN (595)",
+ "UNKNOWN (596)",
+ "UNKNOWN (597)",
+ "UNKNOWN (598)",
+ "UNKNOWN (599)",
+ "UNKNOWN (600)",
+ "UNKNOWN (601)",
+ "UNKNOWN (602)",
+ "UNKNOWN (603)",
+ "UNKNOWN (604)",
+ "UNKNOWN (605)",
+ "UNKNOWN (606)",
+ "UNKNOWN (607)",
+ "UNKNOWN (608)",
+ "UNKNOWN (609)",
+ "UNKNOWN (610)",
+ "UNKNOWN (611)",
+ "UNKNOWN (612)",
+ "UNKNOWN (613)",
+ "UNKNOWN (614)",
+ "UNKNOWN (615)",
+ "UNKNOWN (616)",
+ "UNKNOWN (617)",
+ "UNKNOWN (618)",
+ "UNKNOWN (619)",
+ "UNKNOWN (620)",
+ "UNKNOWN (621)",
+ "UNKNOWN (622)",
+ "UNKNOWN (623)",
+ "UNKNOWN (624)",
+ "UNKNOWN (625)",
+ "UNKNOWN (626)",
+ "UNKNOWN (627)",
+ "UNKNOWN (628)",
+ "UNKNOWN (629)",
+ "UNKNOWN (630)",
+ "UNKNOWN (631)",
+ "UNKNOWN (632)",
+ "UNKNOWN (633)",
+ "UNKNOWN (634)",
+ "UNKNOWN (635)",
+ "UNKNOWN (636)",
+ "UNKNOWN (637)",
+ "UNKNOWN (638)",
+ "UNKNOWN (639)",
+ "UNKNOWN (640)",
+ "UNKNOWN (641)",
+ "UNKNOWN (642)",
+ "UNKNOWN (643)",
+ "UNKNOWN (644)",
+ "UNKNOWN (645)",
+ "UNKNOWN (646)",
+ "UNKNOWN (647)",
+ "UNKNOWN (648)",
+ "UNKNOWN (649)",
+ "UNKNOWN (650)",
+ "UNKNOWN (651)",
+ "UNKNOWN (652)",
+ "UNKNOWN (653)",
+ "UNKNOWN (654)",
+ "UNKNOWN (655)",
+ "UNKNOWN (656)",
+ "UNKNOWN (657)",
+ "UNKNOWN (658)",
+ "UNKNOWN (659)",
+ "UNKNOWN (660)",
+ "UNKNOWN (661)",
+ "UNKNOWN (662)",
+ "UNKNOWN (663)",
+ "UNKNOWN (664)",
+ "UNKNOWN (665)",
+ "UNKNOWN (666)",
+ "UNKNOWN (667)",
+ "UNKNOWN (668)",
+ "UNKNOWN (669)",
+ "UNKNOWN (670)",
+ "UNKNOWN (671)",
+ "UNKNOWN (672)",
+ "WM_MOUSEHOVER",
+ "UNKNOWN (674)",
+ "WM_MOUSELEAVE",
+ "UNKNOWN (676)",
+ "UNKNOWN (677)",
+ "UNKNOWN (678)",
+ "UNKNOWN (679)",
+ "UNKNOWN (680)",
+ "UNKNOWN (681)",
+ "UNKNOWN (682)",
+ "UNKNOWN (683)",
+ "UNKNOWN (684)",
+ "UNKNOWN (685)",
+ "UNKNOWN (686)",
+ "UNKNOWN (687)",
+ "UNKNOWN (688)",
+ "UNKNOWN (689)",
+ "UNKNOWN (690)",
+ "UNKNOWN (691)",
+ "UNKNOWN (692)",
+ "UNKNOWN (693)",
+ "UNKNOWN (694)",
+ "UNKNOWN (695)",
+ "UNKNOWN (696)",
+ "UNKNOWN (697)",
+ "UNKNOWN (698)",
+ "UNKNOWN (699)",
+ "UNKNOWN (700)",
+ "UNKNOWN (701)",
+ "UNKNOWN (702)",
+ "UNKNOWN (703)",
+ "UNKNOWN (704)",
+ "UNKNOWN (705)",
+ "UNKNOWN (706)",
+ "UNKNOWN (707)",
+ "UNKNOWN (708)",
+ "UNKNOWN (709)",
+ "UNKNOWN (710)",
+ "UNKNOWN (711)",
+ "UNKNOWN (712)",
+ "UNKNOWN (713)",
+ "UNKNOWN (714)",
+ "UNKNOWN (715)",
+ "UNKNOWN (716)",
+ "UNKNOWN (717)",
+ "UNKNOWN (718)",
+ "UNKNOWN (719)",
+ "UNKNOWN (720)",
+ "UNKNOWN (721)",
+ "UNKNOWN (722)",
+ "UNKNOWN (723)",
+ "UNKNOWN (724)",
+ "UNKNOWN (725)",
+ "UNKNOWN (726)",
+ "UNKNOWN (727)",
+ "UNKNOWN (728)",
+ "UNKNOWN (729)",
+ "UNKNOWN (730)",
+ "UNKNOWN (731)",
+ "UNKNOWN (732)",
+ "UNKNOWN (733)",
+ "UNKNOWN (734)",
+ "UNKNOWN (735)",
+ "UNKNOWN (736)",
+ "UNKNOWN (737)",
+ "UNKNOWN (738)",
+ "UNKNOWN (739)",
+ "UNKNOWN (740)",
+ "UNKNOWN (741)",
+ "UNKNOWN (742)",
+ "UNKNOWN (743)",
+ "UNKNOWN (744)",
+ "UNKNOWN (745)",
+ "UNKNOWN (746)",
+ "UNKNOWN (747)",
+ "UNKNOWN (748)",
+ "UNKNOWN (749)",
+ "UNKNOWN (750)",
+ "UNKNOWN (751)",
+ "UNKNOWN (752)",
+ "UNKNOWN (753)",
+ "UNKNOWN (754)",
+ "UNKNOWN (755)",
+ "UNKNOWN (756)",
+ "UNKNOWN (757)",
+ "UNKNOWN (758)",
+ "UNKNOWN (759)",
+ "UNKNOWN (760)",
+ "UNKNOWN (761)",
+ "UNKNOWN (762)",
+ "UNKNOWN (763)",
+ "UNKNOWN (764)",
+ "UNKNOWN (765)",
+ "UNKNOWN (766)",
+ "UNKNOWN (767)",
+ "WM_CUT",
+ "WM_COPY",
+ "WM_PASTE",
+ "WM_CLEAR",
+ "WM_UNDO",
+ "WM_RENDERFORMAT",
+ "WM_RENDERALLFORMATS",
+ "WM_DESTROYCLIPBOARD",
+ "WM_DRAWCLIPBOARD",
+ "WM_PAINTCLIPBOARD",
+ "WM_VSCROLLCLIPBOARD",
+ "WM_SIZECLIPBOARD",
+ "WM_ASKCBFORMATNAME",
+ "WM_CHANGECBCHAIN",
+ "WM_HSCROLLCLIPBOARD",
+ "WM_QUERYNEWPALETTE",
+ "WM_PALETTEISCHANGING",
+ "WM_PALETTECHANGED",
+ "WM_HOTKEY",
+ "UNKNOWN (787)",
+ "UNKNOWN (788)",
+ "UNKNOWN (789)",
+ "UNKNOWN (790)",
+ "WM_PRINT",
+ "WM_PRINTCLIENT",
+ "UNKNOWN (793)",
+ "UNKNOWN (794)",
+ "UNKNOWN (795)",
+ "UNKNOWN (796)",
+ "UNKNOWN (797)",
+ "UNKNOWN (798)",
+ "UNKNOWN (799)",
+ "UNKNOWN (800)",
+ "UNKNOWN (801)",
+ "UNKNOWN (802)",
+ "UNKNOWN (803)",
+ "UNKNOWN (804)",
+ "UNKNOWN (805)",
+ "UNKNOWN (806)",
+ "UNKNOWN (807)",
+ "UNKNOWN (808)",
+ "UNKNOWN (809)",
+ "UNKNOWN (810)",
+ "UNKNOWN (811)",
+ "UNKNOWN (812)",
+ "UNKNOWN (813)",
+ "UNKNOWN (814)",
+ "UNKNOWN (815)",
+ "UNKNOWN (816)",
+ "UNKNOWN (817)",
+ "UNKNOWN (818)",
+ "UNKNOWN (819)",
+ "UNKNOWN (820)",
+ "UNKNOWN (821)",
+ "UNKNOWN (822)",
+ "UNKNOWN (823)",
+ "UNKNOWN (824)",
+ "UNKNOWN (825)",
+ "UNKNOWN (826)",
+ "UNKNOWN (827)",
+ "UNKNOWN (828)",
+ "UNKNOWN (829)",
+ "UNKNOWN (830)",
+ "UNKNOWN (831)",
+ "UNKNOWN (832)",
+ "UNKNOWN (833)",
+ "UNKNOWN (834)",
+ "UNKNOWN (835)",
+ "UNKNOWN (836)",
+ "UNKNOWN (837)",
+ "UNKNOWN (838)",
+ "UNKNOWN (839)",
+ "UNKNOWN (840)",
+ "UNKNOWN (841)",
+ "UNKNOWN (842)",
+ "UNKNOWN (843)",
+ "UNKNOWN (844)",
+ "UNKNOWN (845)",
+ "UNKNOWN (846)",
+ "UNKNOWN (847)",
+ "UNKNOWN (848)",
+ "UNKNOWN (849)",
+ "UNKNOWN (850)",
+ "UNKNOWN (851)",
+ "UNKNOWN (852)",
+ "UNKNOWN (853)",
+ "UNKNOWN (854)",
+ "UNKNOWN (855)",
+ "WM_HANDHELDFIRST",
+ "UNKNOWN (857)",
+ "UNKNOWN (858)",
+ "UNKNOWN (859)",
+ "UNKNOWN (860)",
+ "UNKNOWN (861)",
+ "UNKNOWN (862)",
+ "WM_HANDHELDLAST",
+ "WM_AFXFIRST",
+ "UNKNOWN (865)",
+ "UNKNOWN (866)",
+ "UNKNOWN (867)",
+ "UNKNOWN (868)",
+ "UNKNOWN (869)",
+ "UNKNOWN (870)",
+ "UNKNOWN (871)",
+ "UNKNOWN (872)",
+ "UNKNOWN (873)",
+ "UNKNOWN (874)",
+ "UNKNOWN (875)",
+ "UNKNOWN (876)",
+ "UNKNOWN (877)",
+ "UNKNOWN (878)",
+ "UNKNOWN (879)",
+ "UNKNOWN (880)",
+ "UNKNOWN (881)",
+ "UNKNOWN (882)",
+ "UNKNOWN (883)",
+ "UNKNOWN (884)",
+ "UNKNOWN (885)",
+ "UNKNOWN (886)",
+ "UNKNOWN (887)",
+ "UNKNOWN (888)",
+ "UNKNOWN (889)",
+ "UNKNOWN (890)",
+ "UNKNOWN (891)",
+ "UNKNOWN (892)",
+ "UNKNOWN (893)",
+ "UNKNOWN (894)",
+ "WM_AFXLAST",
+ "WM_PENWINFIRST",
+ "UNKNOWN (897)",
+ "UNKNOWN (898)",
+ "UNKNOWN (899)",
+ "UNKNOWN (900)",
+ "UNKNOWN (901)",
+ "UNKNOWN (902)",
+ "UNKNOWN (903)",
+ "UNKNOWN (904)",
+ "UNKNOWN (905)",
+ "UNKNOWN (906)",
+ "UNKNOWN (907)",
+ "UNKNOWN (908)",
+ "UNKNOWN (909)",
+ "UNKNOWN (910)",
+ "WM_PENWINLAST",
+ "UNKNOWN (912)",
+ "UNKNOWN (913)",
+ "UNKNOWN (914)",
+ "UNKNOWN (915)",
+ "UNKNOWN (916)",
+ "UNKNOWN (917)",
+ "UNKNOWN (918)",
+ "UNKNOWN (919)",
+ "UNKNOWN (920)",
+ "UNKNOWN (921)",
+ "UNKNOWN (922)",
+ "UNKNOWN (923)",
+ "UNKNOWN (924)",
+ "UNKNOWN (925)",
+ "UNKNOWN (926)",
+ "UNKNOWN (927)",
+ "UNKNOWN (928)",
+ "UNKNOWN (929)",
+ "UNKNOWN (930)",
+ "UNKNOWN (931)",
+ "UNKNOWN (932)",
+ "UNKNOWN (933)",
+ "UNKNOWN (934)",
+ "UNKNOWN (935)",
+ "UNKNOWN (936)",
+ "UNKNOWN (937)",
+ "UNKNOWN (938)",
+ "UNKNOWN (939)",
+ "UNKNOWN (940)",
+ "UNKNOWN (941)",
+ "UNKNOWN (942)",
+ "UNKNOWN (943)",
+ "UNKNOWN (944)",
+ "UNKNOWN (945)",
+ "UNKNOWN (946)",
+ "UNKNOWN (947)",
+ "UNKNOWN (948)",
+ "UNKNOWN (949)",
+ "UNKNOWN (950)",
+ "UNKNOWN (951)",
+ "UNKNOWN (952)",
+ "UNKNOWN (953)",
+ "UNKNOWN (954)",
+ "UNKNOWN (955)",
+ "UNKNOWN (956)",
+ "UNKNOWN (957)",
+ "UNKNOWN (958)",
+ "UNKNOWN (959)",
+ "UNKNOWN (960)",
+ "UNKNOWN (961)",
+ "UNKNOWN (962)",
+ "UNKNOWN (963)",
+ "UNKNOWN (964)",
+ "UNKNOWN (965)",
+ "UNKNOWN (966)",
+ "UNKNOWN (967)",
+ "UNKNOWN (968)",
+ "UNKNOWN (969)",
+ "UNKNOWN (970)",
+ "UNKNOWN (971)",
+ "UNKNOWN (972)",
+ "UNKNOWN (973)",
+ "UNKNOWN (974)",
+ "UNKNOWN (975)",
+ "UNKNOWN (976)",
+ "UNKNOWN (977)",
+ "UNKNOWN (978)",
+ "UNKNOWN (979)",
+ "UNKNOWN (980)",
+ "UNKNOWN (981)",
+ "UNKNOWN (982)",
+ "UNKNOWN (983)",
+ "UNKNOWN (984)",
+ "UNKNOWN (985)",
+ "UNKNOWN (986)",
+ "UNKNOWN (987)",
+ "UNKNOWN (988)",
+ "UNKNOWN (989)",
+ "UNKNOWN (990)",
+ "UNKNOWN (991)",
+ "UNKNOWN (992)",
+ "UNKNOWN (993)",
+ "UNKNOWN (994)",
+ "UNKNOWN (995)",
+ "UNKNOWN (996)",
+ "UNKNOWN (997)",
+ "UNKNOWN (998)",
+ "UNKNOWN (999)",
+ "UNKNOWN (1000)",
+ "UNKNOWN (1001)",
+ "UNKNOWN (1002)",
+ "UNKNOWN (1003)",
+ "UNKNOWN (1004)",
+ "UNKNOWN (1005)",
+ "UNKNOWN (1006)",
+ "UNKNOWN (1007)",
+ "UNKNOWN (1008)",
+ "UNKNOWN (1009)",
+ "UNKNOWN (1010)",
+ "UNKNOWN (1011)",
+ "UNKNOWN (1012)",
+ "UNKNOWN (1013)",
+ "UNKNOWN (1014)",
+ "UNKNOWN (1015)",
+ "UNKNOWN (1016)",
+ "UNKNOWN (1017)",
+ "UNKNOWN (1018)",
+ "UNKNOWN (1019)",
+ "UNKNOWN (1020)",
+ "UNKNOWN (1021)",
+ "UNKNOWN (1022)",
+ "UNKNOWN (1023)",
+ "WM_USER"
+};
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents.c b/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents.c
new file mode 100644
index 0000000..6cee54a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents.c
@@ -0,0 +1,704 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "SDL_main.h"
+#include "SDL_events.h"
+#include "SDL_syswm.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../wincommon/SDL_lowvideo.h"
+#include "SDL_gapidibvideo.h"
+#include "SDL_vkeys.h"
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+#include "../gapi/SDL_gapivideo.h"
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_WINDIB
+#include "SDL_dibvideo.h"
+#endif
+
+#ifndef WM_APP
+#define WM_APP 0x8000
+#endif
+
+#ifdef _WIN32_WCE
+#define NO_GETKEYBOARDSTATE
+#endif
+
+/* The translation table from a Microsoft VK keysym to a SDL keysym */
+static SDLKey VK_keymap[SDLK_LAST];
+static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed);
+static SDLKey Arrows_keymap[4];
+
+/* Masks for processing the windows KEYDOWN and KEYUP messages */
+#define REPEATED_KEYMASK (1<<30)
+#define EXTENDED_KEYMASK (1<<24)
+
+/* DJM: If the user setup the window for us, we want to save his window proc,
+ and give him a chance to handle some messages. */
+#ifdef STRICT
+#define WNDPROCTYPE WNDPROC
+#else
+#define WNDPROCTYPE FARPROC
+#endif
+static WNDPROCTYPE userWindowProc = NULL;
+
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+
+WPARAM rotateKey(WPARAM key,int direction)
+{
+ if(direction ==0 ) return key;
+
+ switch (key) {
+ case 0x26: /* up */
+ return Arrows_keymap[(2 + direction) % 4];
+ case 0x27: /* right */
+ return Arrows_keymap[(1 + direction) % 4];
+ case 0x28: /* down */
+ return Arrows_keymap[direction % 4];
+ case 0x25: /* left */
+ return Arrows_keymap[(3 + direction) % 4];
+ }
+
+ return key;
+}
+
+static void GapiTransform(GapiInfo *gapiInfo, LONG *x, LONG *y)
+{
+ if(gapiInfo->hiresFix)
+ {
+ *x *= 2;
+ *y *= 2;
+ }
+
+ // 0 3 0
+ if((!gapiInfo->userOrientation && gapiInfo->systemOrientation && !gapiInfo->gapiOrientation) ||
+ // 3 0 3
+ (gapiInfo->userOrientation && !gapiInfo->systemOrientation && gapiInfo->gapiOrientation) ||
+ // 3 0 0
+ (gapiInfo->userOrientation && !gapiInfo->systemOrientation && !gapiInfo->gapiOrientation))
+ {
+ Sint16 temp = *x;
+ *x = SDL_VideoSurface->w - *y;
+ *y = temp;
+ }
+ else
+ // 0 0 0
+ if((!gapiInfo->userOrientation && !gapiInfo->systemOrientation && !gapiInfo->gapiOrientation) ||
+ // 0 0 3
+ (!gapiInfo->userOrientation && !gapiInfo->systemOrientation && gapiInfo->gapiOrientation))
+ {
+ // without changes
+ // *x = *x;
+ // *y = *y;
+ }
+ // default
+ else
+ {
+ // without changes
+ // *x = *x;
+ // *y = *y;
+ }
+}
+#endif
+
+
+/* The main Win32 event handler */
+LRESULT DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ extern int posted;
+
+ switch (msg) {
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN: {
+ SDL_keysym keysym;
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+ if(this->hidden->gapiInfo)
+ {
+ // Drop GAPI artefacts
+ if (wParam == 0x84 || wParam == 0x5B)
+ return 0;
+
+ wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform);
+ }
+#endif
+ /* Ignore repeated keys */
+ if ( lParam&REPEATED_KEYMASK ) {
+ return(0);
+ }
+ switch (wParam) {
+ case VK_CONTROL:
+ if ( lParam&EXTENDED_KEYMASK )
+ wParam = VK_RCONTROL;
+ else
+ wParam = VK_LCONTROL;
+ break;
+ case VK_SHIFT:
+ /* EXTENDED trick doesn't work here */
+ {
+ Uint8 *state = SDL_GetKeyState(NULL);
+ if (state[SDLK_LSHIFT] == SDL_RELEASED && (GetKeyState(VK_LSHIFT) & 0x8000)) {
+ wParam = VK_LSHIFT;
+ } else if (state[SDLK_RSHIFT] == SDL_RELEASED && (GetKeyState(VK_RSHIFT) & 0x8000)) {
+ wParam = VK_RSHIFT;
+ } else {
+ /* Win9x */
+ int sc = HIWORD(lParam) & 0xFF;
+
+ if (sc == 0x2A)
+ wParam = VK_LSHIFT;
+ else
+ if (sc == 0x36)
+ wParam = VK_RSHIFT;
+ else
+ wParam = VK_LSHIFT;
+ }
+ }
+ break;
+ case VK_MENU:
+ if ( lParam&EXTENDED_KEYMASK )
+ wParam = VK_RMENU;
+ else
+ wParam = VK_LMENU;
+ break;
+ }
+#ifdef NO_GETKEYBOARDSTATE
+ /* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */
+ if ( SDL_TranslateUNICODE ) {
+ MSG m;
+
+ m.hwnd = hwnd;
+ m.message = msg;
+ m.wParam = wParam;
+ m.lParam = lParam;
+ m.time = 0;
+ if ( TranslateMessage(&m) && PeekMessage(&m, hwnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) {
+ GetMessage(&m, hwnd, 0, WM_USER);
+ wParam = m.wParam;
+ }
+ }
+#endif /* NO_GETKEYBOARDSTATE */
+ posted = SDL_PrivateKeyboard(SDL_PRESSED,
+ TranslateKey(wParam,HIWORD(lParam),&keysym,1));
+ }
+ return(0);
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP: {
+ SDL_keysym keysym;
+
+#ifdef SDL_VIDEO_DRIVER_GAPI
+ if(this->hidden->gapiInfo)
+ {
+ // Drop GAPI artifacts
+ if (wParam == 0x84 || wParam == 0x5B)
+ return 0;
+
+ wParam = rotateKey(wParam, this->hidden->gapiInfo->coordinateTransform);
+ }
+#endif
+
+ switch (wParam) {
+ case VK_CONTROL:
+ if ( lParam&EXTENDED_KEYMASK )
+ wParam = VK_RCONTROL;
+ else
+ wParam = VK_LCONTROL;
+ break;
+ case VK_SHIFT:
+ /* EXTENDED trick doesn't work here */
+ {
+ Uint8 *state = SDL_GetKeyState(NULL);
+ if (state[SDLK_LSHIFT] == SDL_PRESSED && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
+ wParam = VK_LSHIFT;
+ } else if (state[SDLK_RSHIFT] == SDL_PRESSED && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
+ wParam = VK_RSHIFT;
+ } else {
+ /* Win9x */
+ int sc = HIWORD(lParam) & 0xFF;
+
+ if (sc == 0x2A)
+ wParam = VK_LSHIFT;
+ else
+ if (sc == 0x36)
+ wParam = VK_RSHIFT;
+ else
+ wParam = VK_LSHIFT;
+ }
+ }
+ break;
+ case VK_MENU:
+ if ( lParam&EXTENDED_KEYMASK )
+ wParam = VK_RMENU;
+ else
+ wParam = VK_LMENU;
+ break;
+ }
+ /* Windows only reports keyup for print screen */
+ if ( wParam == VK_SNAPSHOT && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED ) {
+ posted = SDL_PrivateKeyboard(SDL_PRESSED,
+ TranslateKey(wParam,HIWORD(lParam),&keysym,1));
+ }
+ posted = SDL_PrivateKeyboard(SDL_RELEASED,
+ TranslateKey(wParam,HIWORD(lParam),&keysym,0));
+ }
+ return(0);
+#if defined(SC_SCREENSAVE) && defined(SC_MONITORPOWER)
+ case WM_SYSCOMMAND: {
+ const DWORD val = (DWORD) (wParam & 0xFFF0);
+ if ((val == SC_SCREENSAVE) || (val == SC_MONITORPOWER)) {
+ if (this->hidden->dibInfo && !allow_screensaver) {
+ /* Note that this doesn't stop anything on Vista
+ if the screensaver has a password. */
+ return(0);
+ }
+ }
+ }
+ /* Fall through to default processing */
+#endif /* SC_SCREENSAVE && SC_MONITORPOWER */
+
+ default: {
+ /* Only post the event if we're watching for it */
+ if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.hwnd = hwnd;
+ wmmsg.msg = msg;
+ wmmsg.wParam = wParam;
+ wmmsg.lParam = lParam;
+ posted = SDL_PrivateSysWMEvent(&wmmsg);
+
+ /* DJM: If the user isn't watching for private
+ messages in her SDL event loop, then pass it
+ along to any win32 specific window proc.
+ */
+ } else if (userWindowProc) {
+ return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam);
+ }
+ }
+ break;
+ }
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+}
+
+#ifdef _WIN32_WCE
+static BOOL GetLastStylusPos(POINT* ptLast)
+{
+ BOOL bResult = FALSE;
+ UINT nRet;
+ GetMouseMovePoints(ptLast, 1, &nRet);
+ if ( nRet == 1 ) {
+ ptLast->x /= 4;
+ ptLast->y /= 4;
+ bResult = TRUE;
+ }
+ return bResult;
+}
+#endif
+
+static void DIB_GenerateMouseMotionEvent(_THIS)
+{
+ extern int mouse_relative;
+ extern int posted;
+
+ POINT mouse;
+#ifdef _WIN32_WCE
+ if ( !GetCursorPos(&mouse) && !GetLastStylusPos(&mouse) ) return;
+#else
+ if ( !GetCursorPos(&mouse) ) return;
+#endif
+
+ if ( mouse_relative ) {
+ POINT center;
+ center.x = (SDL_VideoSurface->w/2);
+ center.y = (SDL_VideoSurface->h/2);
+ ClientToScreen(SDL_Window, &center);
+
+ mouse.x -= center.x;
+ mouse.y -= center.y;
+ if ( mouse.x || mouse.y ) {
+ SetCursorPos(center.x, center.y);
+ posted = SDL_PrivateMouseMotion(0, 1, (Sint16)mouse.x, (Sint16)mouse.y);
+ }
+ } else {
+ ScreenToClient(SDL_Window, &mouse);
+#ifdef SDL_VIDEO_DRIVER_GAPI
+ if (SDL_VideoSurface && this->hidden->gapiInfo)
+ GapiTransform(this->hidden->gapiInfo, &mouse.x, &mouse.y);
+#endif
+ posted = SDL_PrivateMouseMotion(0, 0, (Sint16)mouse.x, (Sint16)mouse.y);
+ }
+}
+
+void DIB_PumpEvents(_THIS)
+{
+ MSG msg;
+
+ while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
+ if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
+ DispatchMessage(&msg);
+ }
+ }
+
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
+ DIB_GenerateMouseMotionEvent( this );
+ }
+}
+
+static HKL hLayoutUS = NULL;
+
+void DIB_InitOSKeymap(_THIS)
+{
+ int i;
+#ifndef _WIN32_WCE
+ char current_layout[KL_NAMELENGTH];
+
+ GetKeyboardLayoutName(current_layout);
+ //printf("Initial Keyboard Layout Name: '%s'\n", current_layout);
+
+ hLayoutUS = LoadKeyboardLayout("00000409", KLF_NOTELLSHELL);
+
+ if (!hLayoutUS) {
+ //printf("Failed to load US keyboard layout. Using current.\n");
+ hLayoutUS = GetKeyboardLayout(0);
+ }
+ LoadKeyboardLayout(current_layout, KLF_ACTIVATE);
+#else
+#if _WIN32_WCE >=420
+ TCHAR current_layout[KL_NAMELENGTH];
+
+ GetKeyboardLayoutName(current_layout);
+ //printf("Initial Keyboard Layout Name: '%s'\n", current_layout);
+
+ hLayoutUS = LoadKeyboardLayout(L"00000409", 0);
+
+ if (!hLayoutUS) {
+ //printf("Failed to load US keyboard layout. Using current.\n");
+ hLayoutUS = GetKeyboardLayout(0);
+ }
+ LoadKeyboardLayout(current_layout, 0);
+#endif // _WIN32_WCE >=420
+#endif
+ /* Map the VK keysyms */
+ for ( i=0; i<SDL_arraysize(VK_keymap); ++i )
+ VK_keymap[i] = SDLK_UNKNOWN;
+
+ VK_keymap[VK_BACK] = SDLK_BACKSPACE;
+ VK_keymap[VK_TAB] = SDLK_TAB;
+ VK_keymap[VK_CLEAR] = SDLK_CLEAR;
+ VK_keymap[VK_RETURN] = SDLK_RETURN;
+ VK_keymap[VK_PAUSE] = SDLK_PAUSE;
+ VK_keymap[VK_ESCAPE] = SDLK_ESCAPE;
+ VK_keymap[VK_SPACE] = SDLK_SPACE;
+ VK_keymap[VK_APOSTROPHE] = SDLK_QUOTE;
+ VK_keymap[VK_COMMA] = SDLK_COMMA;
+ VK_keymap[VK_MINUS] = SDLK_MINUS;
+ VK_keymap[VK_PERIOD] = SDLK_PERIOD;
+ VK_keymap[VK_SLASH] = SDLK_SLASH;
+ VK_keymap[VK_0] = SDLK_0;
+ VK_keymap[VK_1] = SDLK_1;
+ VK_keymap[VK_2] = SDLK_2;
+ VK_keymap[VK_3] = SDLK_3;
+ VK_keymap[VK_4] = SDLK_4;
+ VK_keymap[VK_5] = SDLK_5;
+ VK_keymap[VK_6] = SDLK_6;
+ VK_keymap[VK_7] = SDLK_7;
+ VK_keymap[VK_8] = SDLK_8;
+ VK_keymap[VK_9] = SDLK_9;
+ VK_keymap[VK_SEMICOLON] = SDLK_SEMICOLON;
+ VK_keymap[VK_EQUALS] = SDLK_EQUALS;
+ VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET;
+ VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH;
+ VK_keymap[VK_OEM_102] = SDLK_LESS;
+ VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET;
+ VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE;
+ VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE;
+ VK_keymap[VK_A] = SDLK_a;
+ VK_keymap[VK_B] = SDLK_b;
+ VK_keymap[VK_C] = SDLK_c;
+ VK_keymap[VK_D] = SDLK_d;
+ VK_keymap[VK_E] = SDLK_e;
+ VK_keymap[VK_F] = SDLK_f;
+ VK_keymap[VK_G] = SDLK_g;
+ VK_keymap[VK_H] = SDLK_h;
+ VK_keymap[VK_I] = SDLK_i;
+ VK_keymap[VK_J] = SDLK_j;
+ VK_keymap[VK_K] = SDLK_k;
+ VK_keymap[VK_L] = SDLK_l;
+ VK_keymap[VK_M] = SDLK_m;
+ VK_keymap[VK_N] = SDLK_n;
+ VK_keymap[VK_O] = SDLK_o;
+ VK_keymap[VK_P] = SDLK_p;
+ VK_keymap[VK_Q] = SDLK_q;
+ VK_keymap[VK_R] = SDLK_r;
+ VK_keymap[VK_S] = SDLK_s;
+ VK_keymap[VK_T] = SDLK_t;
+ VK_keymap[VK_U] = SDLK_u;
+ VK_keymap[VK_V] = SDLK_v;
+ VK_keymap[VK_W] = SDLK_w;
+ VK_keymap[VK_X] = SDLK_x;
+ VK_keymap[VK_Y] = SDLK_y;
+ VK_keymap[VK_Z] = SDLK_z;
+ VK_keymap[VK_DELETE] = SDLK_DELETE;
+
+ VK_keymap[VK_NUMPAD0] = SDLK_KP0;
+ VK_keymap[VK_NUMPAD1] = SDLK_KP1;
+ VK_keymap[VK_NUMPAD2] = SDLK_KP2;
+ VK_keymap[VK_NUMPAD3] = SDLK_KP3;
+ VK_keymap[VK_NUMPAD4] = SDLK_KP4;
+ VK_keymap[VK_NUMPAD5] = SDLK_KP5;
+ VK_keymap[VK_NUMPAD6] = SDLK_KP6;
+ VK_keymap[VK_NUMPAD7] = SDLK_KP7;
+ VK_keymap[VK_NUMPAD8] = SDLK_KP8;
+ VK_keymap[VK_NUMPAD9] = SDLK_KP9;
+ VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD;
+ VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE;
+ VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY;
+ VK_keymap[VK_SUBTRACT] = SDLK_KP_MINUS;
+ VK_keymap[VK_ADD] = SDLK_KP_PLUS;
+
+ VK_keymap[VK_UP] = SDLK_UP;
+ VK_keymap[VK_DOWN] = SDLK_DOWN;
+ VK_keymap[VK_RIGHT] = SDLK_RIGHT;
+ VK_keymap[VK_LEFT] = SDLK_LEFT;
+ VK_keymap[VK_INSERT] = SDLK_INSERT;
+ VK_keymap[VK_HOME] = SDLK_HOME;
+ VK_keymap[VK_END] = SDLK_END;
+ VK_keymap[VK_PRIOR] = SDLK_PAGEUP;
+ VK_keymap[VK_NEXT] = SDLK_PAGEDOWN;
+
+ VK_keymap[VK_F1] = SDLK_F1;
+ VK_keymap[VK_F2] = SDLK_F2;
+ VK_keymap[VK_F3] = SDLK_F3;
+ VK_keymap[VK_F4] = SDLK_F4;
+ VK_keymap[VK_F5] = SDLK_F5;
+ VK_keymap[VK_F6] = SDLK_F6;
+ VK_keymap[VK_F7] = SDLK_F7;
+ VK_keymap[VK_F8] = SDLK_F8;
+ VK_keymap[VK_F9] = SDLK_F9;
+ VK_keymap[VK_F10] = SDLK_F10;
+ VK_keymap[VK_F11] = SDLK_F11;
+ VK_keymap[VK_F12] = SDLK_F12;
+ VK_keymap[VK_F13] = SDLK_F13;
+ VK_keymap[VK_F14] = SDLK_F14;
+ VK_keymap[VK_F15] = SDLK_F15;
+
+ VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK;
+ VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK;
+ VK_keymap[VK_SCROLL] = SDLK_SCROLLOCK;
+ VK_keymap[VK_RSHIFT] = SDLK_RSHIFT;
+ VK_keymap[VK_LSHIFT] = SDLK_LSHIFT;
+ VK_keymap[VK_RCONTROL] = SDLK_RCTRL;
+ VK_keymap[VK_LCONTROL] = SDLK_LCTRL;
+ VK_keymap[VK_RMENU] = SDLK_RALT;
+ VK_keymap[VK_LMENU] = SDLK_LALT;
+ VK_keymap[VK_RWIN] = SDLK_RSUPER;
+ VK_keymap[VK_LWIN] = SDLK_LSUPER;
+
+ VK_keymap[VK_HELP] = SDLK_HELP;
+#ifdef VK_PRINT
+ VK_keymap[VK_PRINT] = SDLK_PRINT;
+#endif
+ VK_keymap[VK_SNAPSHOT] = SDLK_PRINT;
+ VK_keymap[VK_CANCEL] = SDLK_BREAK;
+ VK_keymap[VK_APPS] = SDLK_MENU;
+
+ Arrows_keymap[3] = 0x25;
+ Arrows_keymap[2] = 0x26;
+ Arrows_keymap[1] = 0x27;
+ Arrows_keymap[0] = 0x28;
+}
+
+#define EXTKEYPAD(keypad) ((scancode & 0x100)?(mvke):(keypad))
+
+static int SDL_MapVirtualKey(int scancode, int vkey)
+{
+#ifndef _WIN32_WCE
+ int mvke = MapVirtualKeyEx(scancode & 0xFF, 1, hLayoutUS);
+#else
+ int mvke = MapVirtualKey(scancode & 0xFF, 1);
+#endif
+
+ switch(vkey) {
+ /* These are always correct */
+ case VK_DIVIDE:
+ case VK_MULTIPLY:
+ case VK_SUBTRACT:
+ case VK_ADD:
+ case VK_LWIN:
+ case VK_RWIN:
+ case VK_APPS:
+ /* These are already handled */
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ case VK_LMENU:
+ case VK_RMENU:
+ case VK_SNAPSHOT:
+ case VK_PAUSE:
+ return vkey;
+ }
+ switch(mvke) {
+ /* Distinguish between keypad and extended keys */
+ case VK_INSERT: return EXTKEYPAD(VK_NUMPAD0);
+ case VK_DELETE: return EXTKEYPAD(VK_DECIMAL);
+ case VK_END: return EXTKEYPAD(VK_NUMPAD1);
+ case VK_DOWN: return EXTKEYPAD(VK_NUMPAD2);
+ case VK_NEXT: return EXTKEYPAD(VK_NUMPAD3);
+ case VK_LEFT: return EXTKEYPAD(VK_NUMPAD4);
+ case VK_CLEAR: return EXTKEYPAD(VK_NUMPAD5);
+ case VK_RIGHT: return EXTKEYPAD(VK_NUMPAD6);
+ case VK_HOME: return EXTKEYPAD(VK_NUMPAD7);
+ case VK_UP: return EXTKEYPAD(VK_NUMPAD8);
+ case VK_PRIOR: return EXTKEYPAD(VK_NUMPAD9);
+ }
+ return mvke?mvke:vkey;
+}
+
+static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym *keysym, int pressed)
+{
+ /* Set the keysym information */
+ keysym->scancode = (unsigned char) scancode;
+ keysym->mod = KMOD_NONE;
+ keysym->unicode = 0;
+
+ if ((vkey == VK_RETURN) && (scancode & 0x100)) {
+ /* No VK_ code for the keypad enter key */
+ keysym->sym = SDLK_KP_ENTER;
+ }
+ else {
+ keysym->sym = VK_keymap[SDL_MapVirtualKey(scancode, vkey)];
+ }
+
+ if ( pressed && SDL_TranslateUNICODE ) {
+#ifdef NO_GETKEYBOARDSTATE
+ /* Uh oh, better hope the vkey is close enough.. */
+ if((keysym->sym == vkey) || (vkey > 0x7f))
+ keysym->unicode = vkey;
+#else
+ BYTE keystate[256];
+ Uint16 wchars[2];
+
+ GetKeyboardState(keystate);
+ /* Numlock isn't taken into account in ToUnicode,
+ * so we handle it as a special case here */
+ if ((keystate[VK_NUMLOCK] & 1) && vkey >= VK_NUMPAD0 && vkey <= VK_NUMPAD9)
+ {
+ keysym->unicode = vkey - VK_NUMPAD0 + '0';
+ }
+ else if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
+ {
+ keysym->unicode = wchars[0];
+ }
+#endif /* NO_GETKEYBOARDSTATE */
+ }
+
+#if 0
+ {
+ HKL hLayoutCurrent = GetKeyboardLayout(0);
+ int sc = scancode & 0xFF;
+
+ printf("SYM:%d, VK:0x%02X, SC:0x%04X, US:(1:0x%02X, 3:0x%02X), "
+ "Current:(1:0x%02X, 3:0x%02X)\n",
+ keysym->sym, vkey, scancode,
+ MapVirtualKeyEx(sc, 1, hLayoutUS),
+ MapVirtualKeyEx(sc, 3, hLayoutUS),
+ MapVirtualKeyEx(sc, 1, hLayoutCurrent),
+ MapVirtualKeyEx(sc, 3, hLayoutCurrent)
+ );
+ }
+#endif
+ return(keysym);
+}
+
+int DIB_CreateWindow(_THIS)
+{
+ char *windowid;
+
+ SDL_RegisterApp(NULL, 0, 0);
+
+ windowid = SDL_getenv("SDL_WINDOWID");
+ SDL_windowid = (windowid != NULL);
+ if ( SDL_windowid ) {
+#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
+ /* wince 2.1 does not have strtol */
+ wchar_t *windowid_t = SDL_malloc((SDL_strlen(windowid) + 1) * sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, windowid, -1, windowid_t, SDL_strlen(windowid) + 1);
+ SDL_Window = (HWND)wcstol(windowid_t, NULL, 0);
+ SDL_free(windowid_t);
+#else
+ SDL_Window = (HWND)((size_t)SDL_strtoull(windowid, NULL, 0));
+#endif
+ if ( SDL_Window == NULL ) {
+ SDL_SetError("Couldn't get user specified window");
+ return(-1);
+ }
+
+ /* DJM: we want all event's for the user specified
+ window to be handled by SDL.
+ */
+ userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
+ SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage);
+ } else {
+ SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
+ (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
+ CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL);
+ if ( SDL_Window == NULL ) {
+ SDL_SetError("Couldn't create window");
+ return(-1);
+ }
+ ShowWindow(SDL_Window, SW_HIDE);
+ }
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+
+ return(0);
+}
+
+void DIB_DestroyWindow(_THIS)
+{
+ if ( SDL_windowid ) {
+ SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc);
+ } else {
+ DestroyWindow(SDL_Window);
+ }
+ SDL_UnregisterApp();
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+}
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents_c.h b/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents_c.h
new file mode 100644
index 0000000..236aa68
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_dibevents_c.h
@@ -0,0 +1,35 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "../wincommon/SDL_lowvideo.h"
+
+/* Variables and functions exported by SDL_dibevents.c to other parts
+ of the native video subsystem (SDL_dibvideo.c)
+*/
+extern LONG
+ DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+extern int DIB_CreateWindow(_THIS);
+extern void DIB_DestroyWindow(_THIS);
+
+extern void DIB_PumpEvents(_THIS);
+extern void DIB_InitOSKeymap(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c
new file mode 100644
index 0000000..9f1ffff
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c
@@ -0,0 +1,1499 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* Not yet in the mingw32 cross-compile headers */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN 4
+#endif
+
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_gapidibvideo.h"
+#include "SDL_dibvideo.h"
+#include "../wincommon/SDL_syswm_c.h"
+#include "../wincommon/SDL_sysmouse_c.h"
+#include "SDL_dibevents_c.h"
+#include "../wincommon/SDL_wingl_c.h"
+
+#ifdef _WIN32_WCE
+
+#ifndef DM_DISPLAYORIENTATION
+#define DM_DISPLAYORIENTATION 0x00800000L
+#endif
+#ifndef DM_DISPLAYQUERYORIENTATION
+#define DM_DISPLAYQUERYORIENTATION 0x01000000L
+#endif
+#ifndef DMDO_0
+#define DMDO_0 0
+#endif
+#ifndef DMDO_90
+#define DMDO_90 1
+#endif
+#ifndef DMDO_180
+#define DMDO_180 2
+#endif
+#ifndef DMDO_270
+#define DMDO_270 4
+#endif
+
+#define NO_GETDIBITS
+#define NO_GAMMA_SUPPORT
+ #if _WIN32_WCE < 420
+ #define NO_CHANGEDISPLAYSETTINGS
+ #else
+ #define ChangeDisplaySettings(lpDevMode, dwFlags) ChangeDisplaySettingsEx(NULL, (lpDevMode), 0, (dwFlags), 0)
+ #endif
+#endif
+#ifndef WS_MAXIMIZE
+#define WS_MAXIMIZE 0
+#endif
+#ifndef WS_THICKFRAME
+#define WS_THICKFRAME 0
+#endif
+#ifndef SWP_NOCOPYBITS
+#define SWP_NOCOPYBITS 0
+#endif
+#ifndef PC_NOCOLLAPSE
+#define PC_NOCOLLAPSE 0
+#endif
+
+#ifdef _WIN32_WCE
+// defined and used in SDL_sysevents.c
+extern HINSTANCE aygshell;
+#endif
+
+/* Initialization/Query functions */
+static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DIB_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static void DIB_CheckGamma(_THIS);
+void DIB_SwapGamma(_THIS);
+void DIB_QuitGamma(_THIS);
+int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
+int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
+static void DIB_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DIB_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* Windows message handling functions */
+static void DIB_GrabStaticColors(HWND window);
+static void DIB_ReleaseStaticColors(HWND window);
+static void DIB_Activate(_THIS, BOOL active, BOOL minimized);
+static void DIB_RealizePalette(_THIS);
+static void DIB_PaletteChanged(_THIS, HWND window);
+static void DIB_WinPAINT(_THIS, HDC hdc);
+
+static void DIB_GetWinPos(_THIS, int* px, int *py);
+static void DIB_SetWinPos(_THIS, int x, int y);
+static int DIB_IsWinVisible(_THIS, int recenter);
+static int DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi);
+static int DIB_GetMonitorRect(_THIS, SDL_Rect* rect);
+
+/* helper fn */
+static int DIB_SussScreenDepth();
+
+/* DIB driver bootstrap functions */
+
+static int DIB_Available(void)
+{
+ return(1);
+}
+
+static void DIB_DeleteDevice(SDL_VideoDevice *device)
+{
+ if ( device ) {
+ if ( device->hidden ) {
+ if ( device->hidden->dibInfo ) {
+ SDL_free( device->hidden->dibInfo );
+ }
+ SDL_free(device->hidden);
+ }
+ if ( device->gl_data ) {
+ SDL_free(device->gl_data);
+ }
+ SDL_free(device);
+ }
+}
+
+static SDL_VideoDevice *DIB_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ if(device->hidden){
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ device->hidden->dibInfo = (DibInfo *)SDL_malloc((sizeof(DibInfo)));
+ if(device->hidden->dibInfo == NULL)
+ {
+ SDL_free(device->hidden);
+ device->hidden = NULL;
+ }
+ }
+
+ device->gl_data = (struct SDL_PrivateGLData *)
+ SDL_malloc((sizeof *device->gl_data));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ||
+ (device->gl_data == NULL) ) {
+ SDL_OutOfMemory();
+ DIB_DeleteDevice(device);
+ return(NULL);
+ }
+ SDL_memset(device->hidden->dibInfo, 0, (sizeof *device->hidden->dibInfo));
+ SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
+
+ /* Set the function pointers */
+ device->VideoInit = DIB_VideoInit;
+ device->ListModes = DIB_ListModes;
+ device->SetVideoMode = DIB_SetVideoMode;
+ device->UpdateMouse = WIN_UpdateMouse;
+ device->SetColors = DIB_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = DIB_VideoQuit;
+ device->AllocHWSurface = DIB_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = DIB_LockHWSurface;
+ device->UnlockHWSurface = DIB_UnlockHWSurface;
+ device->FlipHWSurface = NULL;
+ device->FreeHWSurface = DIB_FreeHWSurface;
+ device->SetGammaRamp = DIB_SetGammaRamp;
+ device->GetGammaRamp = DIB_GetGammaRamp;
+#if SDL_VIDEO_OPENGL
+ device->GL_LoadLibrary = WIN_GL_LoadLibrary;
+ device->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ device->GL_GetAttribute = WIN_GL_GetAttribute;
+ device->GL_MakeCurrent = WIN_GL_MakeCurrent;
+ device->GL_SwapBuffers = WIN_GL_SwapBuffers;
+#endif
+ device->SetCaption = WIN_SetWMCaption;
+ device->SetIcon = WIN_SetWMIcon;
+ device->IconifyWindow = WIN_IconifyWindow;
+ device->GrabInput = WIN_GrabInput;
+ device->GetWMInfo = WIN_GetWMInfo;
+ device->FreeWMCursor = WIN_FreeWMCursor;
+ device->CreateWMCursor = WIN_CreateWMCursor;
+ device->ShowWMCursor = WIN_ShowWMCursor;
+ device->WarpWMCursor = WIN_WarpWMCursor;
+ device->CheckMouseMode = WIN_CheckMouseMode;
+ device->InitOSKeymap = DIB_InitOSKeymap;
+ device->PumpEvents = DIB_PumpEvents;
+
+ device->GetWindowPos = DIB_GetWinPos;
+ device->SetWindowPos = DIB_SetWinPos;
+ device->IsWindowVisible = DIB_IsWinVisible;
+ device->GetMonitorDPI = DIB_GetMonitorDPI;
+ device->GetMonitorRect = DIB_GetMonitorRect;
+
+ /* Set up the windows message handling functions */
+ WIN_Activate = DIB_Activate;
+ WIN_RealizePalette = DIB_RealizePalette;
+ WIN_PaletteChanged = DIB_PaletteChanged;
+ WIN_WinPAINT = DIB_WinPAINT;
+ HandleMessage = DIB_HandleMessage;
+
+ device->free = DIB_DeleteDevice;
+
+ /* We're finally ready */
+ return device;
+}
+
+VideoBootStrap WINDIB_bootstrap = {
+ "windib", "Win95/98/NT/2000/CE GDI",
+ DIB_Available, DIB_CreateDevice
+};
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ SDL_Rect *a = *(SDL_Rect **)va;
+ SDL_Rect *b = *(SDL_Rect **)vb;
+ if ( a->w == b->w )
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+
+static int DIB_AddMode(_THIS, int bpp, int w, int h)
+{
+ SDL_Rect *mode;
+ int i, index;
+ int next_mode;
+
+ /* Check to see if we already have this mode */
+ if ( bpp < 8 || bpp > 32 ) { /* Not supported */
+ return(0);
+ }
+ index = ((bpp+7)/8)-1;
+ for ( i=0; i<SDL_nummodes[index]; ++i ) {
+ mode = SDL_modelist[index][i];
+ if ( (mode->w == w) && (mode->h == h) ) {
+ return(0);
+ }
+ }
+
+ /* Set up the new video mode rectangle */
+ mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
+ if ( mode == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ mode->x = 0;
+ mode->y = 0;
+ mode->w = w;
+ mode->h = h;
+
+ /* Allocate the new list of modes, and fill in the new mode */
+ next_mode = SDL_nummodes[index];
+ SDL_modelist[index] = (SDL_Rect **)
+ SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[index] == NULL ) {
+ SDL_OutOfMemory();
+ SDL_nummodes[index] = 0;
+ SDL_free(mode);
+ return(-1);
+ }
+ SDL_modelist[index][next_mode] = mode;
+ SDL_modelist[index][next_mode+1] = NULL;
+ SDL_nummodes[index]++;
+
+ return(0);
+}
+
+static void DIB_CreatePalette(_THIS, int bpp)
+{
+/* RJR: March 28, 2000
+ moved palette creation here from "DIB_VideoInit" */
+
+ LOGPALETTE *palette;
+ HDC hdc;
+ int ncolors;
+
+ ncolors = (1 << bpp);
+ palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
+ ncolors*sizeof(PALETTEENTRY));
+ palette->palVersion = 0x300;
+ palette->palNumEntries = ncolors;
+ hdc = GetDC(SDL_Window);
+ GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
+ ReleaseDC(SDL_Window, hdc);
+ screen_pal = CreatePalette(palette);
+ screen_logpal = palette;
+}
+
+int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ const char *env = NULL;
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ int i;
+ DEVMODE settings;
+#endif
+
+ /* Create the window */
+ if ( DIB_CreateWindow(this) < 0 ) {
+ return(-1);
+ }
+
+#if !SDL_AUDIO_DISABLED
+ DX5_SoundFocus(SDL_Window);
+#endif
+
+ /* Determine the screen depth */
+ vformat->BitsPerPixel = DIB_SussScreenDepth();
+ switch (vformat->BitsPerPixel) {
+ case 15:
+ vformat->Rmask = 0x00007c00;
+ vformat->Gmask = 0x000003e0;
+ vformat->Bmask = 0x0000001f;
+ vformat->BitsPerPixel = 16;
+ break;
+ case 16:
+ vformat->Rmask = 0x0000f800;
+ vformat->Gmask = 0x000007e0;
+ vformat->Bmask = 0x0000001f;
+ break;
+ case 24:
+ case 32:
+ /* GDI defined as 8-8-8 */
+ vformat->Rmask = 0x00ff0000;
+ vformat->Gmask = 0x0000ff00;
+ vformat->Bmask = 0x000000ff;
+ break;
+ default:
+ break;
+ }
+
+ /* See if gamma is supported on this screen */
+ DIB_CheckGamma(this);
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+
+ settings.dmSize = sizeof(DEVMODE);
+ settings.dmDriverExtra = 0;
+#ifdef _WIN32_WCE
+ settings.dmFields = DM_DISPLAYQUERYORIENTATION;
+ this->hidden->supportRotation = ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL;
+#endif
+ /* Query for the desktop resolution */
+ SDL_desktop_mode.dmSize = sizeof(SDL_desktop_mode);
+ SDL_desktop_mode.dmDriverExtra = 0;
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
+ this->info.current_w = SDL_desktop_mode.dmPelsWidth;
+ this->info.current_h = SDL_desktop_mode.dmPelsHeight;
+
+ /* Query for the list of available video modes */
+ for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
+ DIB_AddMode(this, settings.dmBitsPerPel,
+ settings.dmPelsWidth, settings.dmPelsHeight);
+#ifdef _WIN32_WCE
+ if( this->hidden->supportRotation )
+ DIB_AddMode(this, settings.dmBitsPerPel,
+ settings.dmPelsHeight, settings.dmPelsWidth);
+#endif
+ }
+ /* Sort the mode lists */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_nummodes[i] > 0 ) {
+ SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
+ }
+ }
+#else
+ // WinCE and fullscreen mode:
+ // We use only vformat->BitsPerPixel that allow SDL to
+ // emulate other bpp (8, 32) and use triple buffer,
+ // because SDL surface conversion is much faster than the WinCE one.
+ // Although it should be tested on devices with graphics accelerator.
+
+ DIB_AddMode(this, vformat->BitsPerPixel,
+ GetDeviceCaps(GetDC(NULL), HORZRES),
+ GetDeviceCaps(GetDC(NULL), VERTRES));
+
+#endif /* !NO_CHANGEDISPLAYSETTINGS */
+
+ /* Grab an identity palette if we are in a palettized mode */
+ if ( vformat->BitsPerPixel <= 8 ) {
+ /* RJR: March 28, 2000
+ moved palette creation to "DIB_CreatePalette" */
+ DIB_CreatePalette(this, vformat->BitsPerPixel);
+ }
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+#ifdef _WIN32_WCE
+ this->hidden->origRotation = -1;
+#endif
+
+ /* Allow environment override of screensaver disable. */
+ env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
+ if ( env ) {
+ allow_screensaver = SDL_atoi(env);
+ } else {
+#ifdef SDL_VIDEO_DISABLE_SCREENSAVER
+ allow_screensaver = 0;
+#else
+ allow_screensaver = 1;
+#endif
+ }
+
+ /* We're done! */
+ return(0);
+}
+
+/* We support any format at any dimension */
+SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+ } else {
+ return((SDL_Rect **)-1);
+ }
+}
+
+
+/*
+ Helper fn to work out which screen depth windows is currently using.
+ 15 bit mode is considered 555 format, 16 bit is 565.
+ returns 0 for unknown mode.
+ (Derived from code in sept 1999 Windows Developer Journal
+ http://www.wdj.com/code/archive.html)
+*/
+static int DIB_SussScreenDepth()
+{
+#ifdef NO_GETDIBITS
+ int depth;
+ HDC hdc;
+
+ hdc = GetDC(SDL_Window);
+ depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
+ ReleaseDC(SDL_Window, hdc);
+ return(depth);
+#else
+ int depth;
+ int dib_size;
+ LPBITMAPINFOHEADER dib_hdr;
+ HDC hdc;
+ HBITMAP hbm;
+
+ /* Allocate enough space for a DIB header plus palette (for
+ * 8-bit modes) or bitfields (for 16- and 32-bit modes)
+ */
+ dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
+ dib_hdr = (LPBITMAPINFOHEADER) SDL_malloc(dib_size);
+ SDL_memset(dib_hdr, 0, dib_size);
+ dib_hdr->biSize = sizeof(BITMAPINFOHEADER);
+
+ /* Get a device-dependent bitmap that's compatible with the
+ screen.
+ */
+ hdc = GetDC(NULL);
+ hbm = CreateCompatibleBitmap( hdc, 1, 1 );
+
+ /* Convert the DDB to a DIB. We need to call GetDIBits twice:
+ * the first call just fills in the BITMAPINFOHEADER; the
+ * second fills in the bitfields or palette.
+ */
+ GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
+ GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
+ DeleteObject(hbm);
+ ReleaseDC(NULL, hdc);
+
+ depth = 0;
+ switch( dib_hdr->biBitCount )
+ {
+ case 8: depth = 8; break;
+ case 24: depth = 24; break;
+ case 32: depth = 32; break;
+ case 16:
+ if( dib_hdr->biCompression == BI_BITFIELDS ) {
+ /* check the red mask */
+ switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) {
+ case 0xf800: depth = 16; break; /* 565 */
+ case 0x7c00: depth = 15; break; /* 555 */
+ }
+ }
+ }
+ SDL_free(dib_hdr);
+ return depth;
+#endif /* NO_GETDIBITS */
+}
+
+
+/* Various screen update functions available */
+static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+static void DIB_ResizeWindow(_THIS, int width, int height, int prev_width, int prev_height, Uint32 flags)
+{
+ RECT bounds;
+ int x, y;
+
+#ifndef _WIN32_WCE
+ /* Resize the window */
+ if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
+#else
+ if ( !SDL_windowid ) {
+#endif
+ HWND top;
+ UINT swp_flags;
+ const char *window = NULL;
+ const char *center = NULL;
+
+ if ( width != prev_width || height != prev_height ) {
+ window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
+ center = SDL_getenv("SDL_VIDEO_CENTERED");
+ if ( window ) {
+ if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
+ SDL_windowX = x;
+ SDL_windowY = y;
+ }
+ if ( SDL_strcmp(window, "center") == 0 ) {
+ center = window;
+ }
+ }
+ }
+ swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
+
+ bounds.left = SDL_windowX;
+ bounds.top = SDL_windowY;
+ bounds.right = SDL_windowX+width;
+ bounds.bottom = SDL_windowY+height;
+#ifndef _WIN32_WCE
+ AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
+#else
+ // The bMenu parameter must be FALSE; menu bars are not supported
+ AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0);
+#endif
+ width = bounds.right-bounds.left;
+ height = bounds.bottom-bounds.top;
+ if ( (flags & SDL_FULLSCREEN) ) {
+ x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ } else if ( center ) {
+ x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ } else if ( SDL_windowX || SDL_windowY || window ) {
+ x = bounds.left;
+ y = bounds.top;
+ } else {
+ x = y = -1;
+ swp_flags |= SWP_NOMOVE;
+ }
+ if ( flags & SDL_FULLSCREEN ) {
+ top = HWND_TOPMOST;
+ } else {
+ top = HWND_NOTOPMOST;
+ }
+ SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+ if ( !(flags & SDL_FULLSCREEN) ) {
+ SDL_windowX = SDL_bounds.left;
+ SDL_windowY = SDL_bounds.top;
+ }
+ if ( GetParent(SDL_Window) == NULL ) {
+ SetForegroundWindow(SDL_Window);
+ }
+ }
+}
+
+SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ SDL_Surface *video;
+ int prev_w, prev_h;
+ Uint32 prev_flags;
+ DWORD style;
+ const DWORD directstyle =
+ (WS_POPUP);
+ const DWORD windowstyle =
+ (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+ const DWORD resizestyle =
+ (WS_THICKFRAME|WS_MAXIMIZEBOX);
+ int binfo_size;
+ BITMAPINFO *binfo;
+ HDC hdc;
+ Uint32 Rmask, Gmask, Bmask;
+
+ prev_w = current->w;
+ prev_h = current->h;
+ prev_flags = current->flags;
+
+ /*
+ * Special case for OpenGL windows...since the app needs to call
+ * SDL_SetVideoMode() in response to resize events to continue to
+ * function, but WGL handles the GL context details behind the scenes,
+ * there's no sense in tearing the context down just to rebuild it
+ * to what it already was...tearing it down sacrifices your GL state
+ * and uploaded textures. So if we're requesting the same video mode
+ * attributes just resize the window and return immediately.
+ */
+ if ( SDL_Window &&
+ ((current->flags & ~SDL_ANYFORMAT) == (flags & ~SDL_ANYFORMAT)) &&
+ (current->format->BitsPerPixel == bpp) &&
+ (flags & SDL_OPENGL) &&
+ !(flags & SDL_FULLSCREEN) ) { /* probably not safe for fs */
+ current->w = width;
+ current->h = height;
+ SDL_resizing = 1;
+ DIB_ResizeWindow(this, width, height, prev_w, prev_h, flags);
+ SDL_resizing = 0;
+ return current;
+ }
+
+ /* Clean up any GL context that may be hanging around */
+ if ( current->flags & SDL_OPENGL ) {
+ WIN_GL_ShutDown(this);
+ }
+ SDL_resizing = 1;
+
+ /* Recalculate the bitmasks if necessary */
+ if ( bpp == current->format->BitsPerPixel ) {
+ video = current;
+ } else {
+ switch (bpp) {
+ case 15:
+ case 16:
+ if ( DIB_SussScreenDepth() == 15 ) {
+ /* 5-5-5 */
+ Rmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Bmask = 0x0000001f;
+ } else {
+ /* 5-6-5 */
+ Rmask = 0x0000f800;
+ Gmask = 0x000007e0;
+ Bmask = 0x0000001f;
+ }
+ break;
+ case 24:
+ case 32:
+ /* GDI defined as 8-8-8 */
+ Rmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Bmask = 0x000000ff;
+ break;
+ default:
+ Rmask = 0x00000000;
+ Gmask = 0x00000000;
+ Bmask = 0x00000000;
+ break;
+ }
+ video = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ 0, 0, bpp, Rmask, Gmask, Bmask, 0);
+ if ( video == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ }
+
+ /* Fill in part of the video surface */
+ video->flags = 0; /* Clear flags */
+ video->w = width;
+ video->h = height;
+ video->pitch = SDL_CalculatePitch(video);
+
+ /* Small fix for WinCE/Win32 - when activating window
+ SDL_VideoSurface is equal to zero, so activating code
+ is not called properly for fullscreen windows because
+ macros WINDIB_FULLSCREEN uses SDL_VideoSurface
+ */
+ SDL_VideoSurface = video;
+
+#if defined(_WIN32_WCE)
+ if ( flags & SDL_FULLSCREEN )
+ video->flags |= SDL_FULLSCREEN;
+#endif
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ /* Set fullscreen mode if appropriate */
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ DEVMODE settings;
+ BOOL changed;
+
+ SDL_memset(&settings, 0, sizeof(DEVMODE));
+ settings.dmSize = sizeof(DEVMODE);
+
+#ifdef _WIN32_WCE
+ // try to rotate screen to fit requested resolution
+ if( this->hidden->supportRotation )
+ {
+ DWORD rotation;
+
+ // ask current mode
+ settings.dmFields = DM_DISPLAYORIENTATION;
+ ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
+ rotation = settings.dmDisplayOrientation;
+
+ if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
+ && (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
+ {
+ switch( rotation )
+ {
+ case DMDO_0:
+ settings.dmDisplayOrientation = DMDO_90;
+ break;
+ case DMDO_270:
+ settings.dmDisplayOrientation = DMDO_180;
+ break;
+ }
+ if( settings.dmDisplayOrientation != rotation )
+ {
+ // go to landscape
+ this->hidden->origRotation = rotation;
+ ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
+ }
+ }
+ if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
+ && (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
+ {
+ switch( rotation )
+ {
+ case DMDO_90:
+ settings.dmDisplayOrientation = DMDO_0;
+ break;
+ case DMDO_180:
+ settings.dmDisplayOrientation = DMDO_270;
+ break;
+ }
+ if( settings.dmDisplayOrientation != rotation )
+ {
+ // go to portrait
+ this->hidden->origRotation = rotation;
+ ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
+ }
+ }
+
+ }
+#endif
+
+#ifndef _WIN32_WCE
+ settings.dmBitsPerPel = video->format->BitsPerPixel;
+ settings.dmPelsWidth = width;
+ settings.dmPelsHeight = height;
+ settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
+ if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
+ height <= (int)SDL_desktop_mode.dmPelsHeight ) {
+ settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
+ settings.dmFields |= DM_DISPLAYFREQUENCY;
+ }
+ changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
+ if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
+ settings.dmFields &= ~DM_DISPLAYFREQUENCY;
+ changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
+ }
+#else
+ changed = 1;
+#endif
+ if ( changed ) {
+ video->flags |= SDL_FULLSCREEN;
+ SDL_fullscreen_mode = settings;
+ }
+
+ }
+#endif /* !NO_CHANGEDISPLAYSETTINGS */
+
+ /* Reset the palette and create a new one if necessary */
+ if ( grab_palette ) {
+ DIB_ReleaseStaticColors(SDL_Window);
+ grab_palette = FALSE;
+ }
+ if ( screen_pal != NULL ) {
+ /* RJR: March 28, 2000
+ delete identity palette if switching from a palettized mode */
+ DeleteObject(screen_pal);
+ screen_pal = NULL;
+ }
+ if ( screen_logpal != NULL ) {
+ SDL_free(screen_logpal);
+ screen_logpal = NULL;
+ }
+
+ if ( bpp <= 8 )
+ {
+ /* RJR: March 28, 2000
+ create identity palette switching to a palettized mode */
+ DIB_CreatePalette(this, bpp);
+ }
+
+ style = GetWindowLong(SDL_Window, GWL_STYLE);
+ style &= ~(resizestyle|WS_MAXIMIZE);
+ if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ } else {
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ ChangeDisplaySettings(NULL, 0);
+ }
+#endif
+ if ( flags & SDL_NOFRAME ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ video->flags |= SDL_NOFRAME;
+ } else {
+ style &= ~directstyle;
+ style |= windowstyle;
+ if ( flags & SDL_RESIZABLE ) {
+ style |= resizestyle;
+ video->flags |= SDL_RESIZABLE;
+ }
+ }
+#if WS_MAXIMIZE && !defined(_WIN32_WCE)
+ if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+ }
+
+ /* DJM: Don't piss of anyone who has setup his own window */
+ if ( !SDL_windowid )
+ SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+ /* Delete the old bitmap if necessary */
+ if ( screen_bmp != NULL ) {
+ DeleteObject(screen_bmp);
+ }
+ if ( ! (flags & SDL_OPENGL) ) {
+ BOOL is16bitmode = (video->format->BytesPerPixel == 2);
+
+ /* Suss out the bitmap info header */
+ binfo_size = sizeof(*binfo);
+ if( is16bitmode ) {
+ /* 16bit modes, palette area used for rgb bitmasks */
+ binfo_size += 3*sizeof(DWORD);
+ } else if ( video->format->palette ) {
+ binfo_size += video->format->palette->ncolors *
+ sizeof(RGBQUAD);
+ }
+ binfo = (BITMAPINFO *)SDL_malloc(binfo_size);
+ if ( ! binfo ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ binfo->bmiHeader.biWidth = video->w;
+ binfo->bmiHeader.biHeight = -video->h; /* -ve for topdown bitmap */
+ binfo->bmiHeader.biPlanes = 1;
+ binfo->bmiHeader.biSizeImage = video->h * video->pitch;
+ binfo->bmiHeader.biXPelsPerMeter = 0;
+ binfo->bmiHeader.biYPelsPerMeter = 0;
+ binfo->bmiHeader.biClrUsed = 0;
+ binfo->bmiHeader.biClrImportant = 0;
+ binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;
+
+ if ( is16bitmode ) {
+ /* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
+ binfo->bmiHeader.biCompression = BI_BITFIELDS;
+ ((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
+ ((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
+ ((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
+ } else {
+ binfo->bmiHeader.biCompression = BI_RGB; /* BI_BITFIELDS for 565 vs 555 */
+ if ( video->format->palette ) {
+ SDL_memset(binfo->bmiColors, 0,
+ video->format->palette->ncolors*sizeof(RGBQUAD));
+ }
+ }
+
+ /* Create the offscreen bitmap buffer */
+ hdc = GetDC(SDL_Window);
+ screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
+ (void **)(&video->pixels), NULL, 0);
+ ReleaseDC(SDL_Window, hdc);
+ SDL_free(binfo);
+ if ( screen_bmp == NULL ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SDL_SetError("Couldn't create DIB section");
+ return(NULL);
+ }
+ this->UpdateRects = DIB_NormalUpdate;
+
+ /* Set video surface flags */
+ if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) {
+ grab_palette = TRUE;
+ }
+ if ( screen_pal ) {
+ /* BitBlt() maps colors for us */
+ video->flags |= SDL_HWPALETTE;
+ }
+ }
+ DIB_ResizeWindow(this, width, height, prev_w, prev_h, flags);
+ SDL_resizing = 0;
+
+ /* Set up for OpenGL */
+ if ( flags & SDL_OPENGL ) {
+ if ( WIN_GL_SetupWindow(this) < 0 ) {
+ return(NULL);
+ }
+ video->flags |= SDL_OPENGL;
+ }
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+
+ /* We're live! */
+ return(video);
+}
+
+/* We don't actually allow hardware surfaces in the DIB driver */
+static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ HDC hdc, mdc;
+ int i;
+
+ hdc = GetDC(SDL_Window);
+ if ( screen_pal ) {
+ SelectPalette(hdc, screen_pal, FALSE);
+ }
+ mdc = CreateCompatibleDC(hdc);
+ SelectObject(mdc, screen_bmp);
+ for ( i=0; i<numrects; ++i ) {
+ BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
+ mdc, rects[i].x, rects[i].y, SRCCOPY);
+ }
+ DeleteDC(mdc);
+ ReleaseDC(SDL_Window, hdc);
+}
+
+static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b)
+{
+ PALETTEENTRY *entry;
+ int i;
+ int nentries = pal->palNumEntries;
+
+ for ( i = 0; i < nentries; ++i ) {
+ entry = &pal->palPalEntry[i];
+ if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b)
+{
+ PALETTEENTRY *entry;
+ BOOL moved = 0;
+
+ entry = &pal->palPalEntry[index];
+ if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) {
+ int found = FindPaletteIndex(pal, r, g, b);
+ if ( found >= 0 ) {
+ pal->palPalEntry[found] = *entry;
+ }
+ entry->peRed = r;
+ entry->peGreen = g;
+ entry->peBlue = b;
+ moved = 1;
+ }
+ entry->peFlags = 0;
+
+ return moved;
+}
+
+int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
+ HDC hdc, mdc;
+ RGBQUAD *pal;
+#else
+ HDC hdc;
+#endif
+ int i;
+ int moved_entries = 0;
+
+ /* Update the display palette */
+ hdc = GetDC(SDL_Window);
+ if ( screen_pal ) {
+ PALETTEENTRY *entry;
+
+ for ( i=0; i<ncolors; ++i ) {
+ entry = &screen_logpal->palPalEntry[firstcolor+i];
+ entry->peRed = colors[i].r;
+ entry->peGreen = colors[i].g;
+ entry->peBlue = colors[i].b;
+ entry->peFlags = PC_NOCOLLAPSE;
+ }
+#if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
+ /* Check to make sure black and white are in position */
+ if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
+ moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00);
+ moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff);
+ }
+ /* FIXME:
+ If we don't have full access to the palette, what we
+ really want to do is find the 236 most diverse colors
+ in the desired palette, set those entries (10-245) and
+ then map everything into the new system palette.
+ */
+#endif
+
+#ifndef _WIN32_WCE
+ /* Copy the entries into the system palette */
+ UnrealizeObject(screen_pal);
+#endif
+ SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry);
+ SelectPalette(hdc, screen_pal, FALSE);
+ RealizePalette(hdc);
+ }
+
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
+ /* Copy palette colors into DIB palette */
+ pal = SDL_stack_alloc(RGBQUAD, ncolors);
+ for ( i=0; i<ncolors; ++i ) {
+ pal[i].rgbRed = colors[i].r;
+ pal[i].rgbGreen = colors[i].g;
+ pal[i].rgbBlue = colors[i].b;
+ pal[i].rgbReserved = 0;
+ }
+
+ /* Set the DIB palette and update the display */
+ mdc = CreateCompatibleDC(hdc);
+ SelectObject(mdc, screen_bmp);
+ SetDIBColorTable(mdc, firstcolor, ncolors, pal);
+ if ( moved_entries || !grab_palette ) {
+ BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
+ mdc, 0, 0, SRCCOPY);
+ }
+ DeleteDC(mdc);
+ SDL_stack_free(pal);
+#endif
+ ReleaseDC(SDL_Window, hdc);
+ return(1);
+}
+
+
+static void DIB_CheckGamma(_THIS)
+{
+#ifndef NO_GAMMA_SUPPORT
+ HDC hdc;
+ WORD ramp[3*256];
+
+ /* If we fail to get gamma, disable gamma control */
+ hdc = GetDC(SDL_Window);
+ if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
+ this->GetGammaRamp = NULL;
+ this->SetGammaRamp = NULL;
+ }
+ ReleaseDC(SDL_Window, hdc);
+#endif /* !NO_GAMMA_SUPPORT */
+}
+void DIB_SwapGamma(_THIS)
+{
+#ifndef NO_GAMMA_SUPPORT
+ HDC hdc;
+
+ if ( gamma_saved ) {
+ hdc = GetDC(SDL_Window);
+ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
+ /* About to leave active state, restore gamma */
+ SetDeviceGammaRamp(hdc, gamma_saved);
+ } else {
+ /* About to enter active state, set game gamma */
+ GetDeviceGammaRamp(hdc, gamma_saved);
+ SetDeviceGammaRamp(hdc, this->gamma);
+ }
+ ReleaseDC(SDL_Window, hdc);
+ }
+#endif /* !NO_GAMMA_SUPPORT */
+}
+void DIB_QuitGamma(_THIS)
+{
+#ifndef NO_GAMMA_SUPPORT
+ if ( gamma_saved ) {
+ /* Restore the original gamma if necessary */
+ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
+ HDC hdc;
+
+ hdc = GetDC(SDL_Window);
+ SetDeviceGammaRamp(hdc, gamma_saved);
+ ReleaseDC(SDL_Window, hdc);
+ }
+
+ /* Free the saved gamma memory */
+ SDL_free(gamma_saved);
+ gamma_saved = 0;
+ }
+#endif /* !NO_GAMMA_SUPPORT */
+}
+
+int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
+{
+#ifdef NO_GAMMA_SUPPORT
+ SDL_SetError("SDL compiled without gamma ramp support");
+ return -1;
+#else
+ HDC hdc;
+ BOOL succeeded;
+
+ /* Set the ramp for the display */
+ if ( ! gamma_saved ) {
+ gamma_saved = (WORD *)SDL_malloc(3*256*sizeof(*gamma_saved));
+ if ( ! gamma_saved ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ hdc = GetDC(SDL_Window);
+ GetDeviceGammaRamp(hdc, gamma_saved);
+ ReleaseDC(SDL_Window, hdc);
+ }
+ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
+ hdc = GetDC(SDL_Window);
+ succeeded = SetDeviceGammaRamp(hdc, ramp);
+ ReleaseDC(SDL_Window, hdc);
+ } else {
+ succeeded = TRUE;
+ }
+ return succeeded ? 0 : -1;
+#endif /* !NO_GAMMA_SUPPORT */
+}
+
+int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
+{
+#ifdef NO_GAMMA_SUPPORT
+ SDL_SetError("SDL compiled without gamma ramp support");
+ return -1;
+#else
+ HDC hdc;
+ BOOL succeeded;
+
+ /* Get the ramp from the display */
+ hdc = GetDC(SDL_Window);
+ succeeded = GetDeviceGammaRamp(hdc, ramp);
+ ReleaseDC(SDL_Window, hdc);
+ return succeeded ? 0 : -1;
+#endif /* !NO_GAMMA_SUPPORT */
+}
+
+void DIB_VideoQuit(_THIS)
+{
+ int i, j;
+
+ /* Destroy the window and everything associated with it */
+ if ( SDL_Window ) {
+ /* Delete the screen bitmap (also frees screen->pixels) */
+ if ( this->screen ) {
+ if ( grab_palette ) {
+ DIB_ReleaseStaticColors(SDL_Window);
+ }
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ if ( this->screen->flags & SDL_FULLSCREEN ) {
+ ChangeDisplaySettings(NULL, 0);
+ ShowWindow(SDL_Window, SW_HIDE);
+ }
+#endif
+ if ( this->screen->flags & SDL_OPENGL ) {
+ WIN_GL_ShutDown(this);
+ }
+ this->screen->pixels = NULL;
+ }
+ if ( screen_pal != NULL ) {
+ DeleteObject(screen_pal);
+ screen_pal = NULL;
+ }
+ if ( screen_logpal != NULL ) {
+ SDL_free(screen_logpal);
+ screen_logpal = NULL;
+ }
+ if ( screen_bmp ) {
+ DeleteObject(screen_bmp);
+ screen_bmp = NULL;
+ }
+ if ( screen_icn ) {
+ DestroyIcon(screen_icn);
+ screen_icn = NULL;
+ }
+ DIB_QuitGamma(this);
+ DIB_DestroyWindow(this);
+
+ SDL_Window = NULL;
+
+#if defined(_WIN32_WCE)
+
+// Unload wince aygshell library to prevent leak
+ if( aygshell )
+ {
+ FreeLibrary(aygshell);
+ aygshell = NULL;
+ }
+#endif
+ }
+
+ for ( i=0; i < SDL_arraysize(SDL_modelist); ++i ) {
+ if ( !SDL_modelist[i] ) {
+ continue;
+ }
+ for ( j=0; SDL_modelist[i][j]; ++j ) {
+ SDL_free(SDL_modelist[i][j]);
+ }
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ SDL_nummodes[i] = 0;
+ }
+}
+
+/* Exported for the windows message loop only */
+static void DIB_GrabStaticColors(HWND window)
+{
+#if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
+ HDC hdc;
+
+ hdc = GetDC(window);
+ SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
+ if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
+ SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
+ }
+ ReleaseDC(window, hdc);
+#endif
+}
+static void DIB_ReleaseStaticColors(HWND window)
+{
+#if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
+ HDC hdc;
+
+ hdc = GetDC(window);
+ SetSystemPaletteUse(hdc, SYSPAL_STATIC);
+ ReleaseDC(window, hdc);
+#endif
+}
+static void DIB_Activate(_THIS, BOOL active, BOOL minimized)
+{
+ if ( grab_palette ) {
+ if ( !active ) {
+ DIB_ReleaseStaticColors(SDL_Window);
+ DIB_RealizePalette(this);
+ } else if ( !minimized ) {
+ DIB_GrabStaticColors(SDL_Window);
+ DIB_RealizePalette(this);
+ }
+ }
+}
+static void DIB_RealizePalette(_THIS)
+{
+ if ( screen_pal != NULL ) {
+ HDC hdc;
+
+ hdc = GetDC(SDL_Window);
+#ifndef _WIN32_WCE
+ UnrealizeObject(screen_pal);
+#endif
+ SelectPalette(hdc, screen_pal, FALSE);
+ if ( RealizePalette(hdc) ) {
+ InvalidateRect(SDL_Window, NULL, FALSE);
+ }
+ ReleaseDC(SDL_Window, hdc);
+ }
+}
+static void DIB_PaletteChanged(_THIS, HWND window)
+{
+ if ( window != SDL_Window ) {
+ DIB_RealizePalette(this);
+ }
+}
+
+/* Exported for the windows message loop only */
+static void DIB_WinPAINT(_THIS, HDC hdc)
+{
+ HDC mdc;
+
+ if ( screen_pal ) {
+ SelectPalette(hdc, screen_pal, FALSE);
+ }
+ mdc = CreateCompatibleDC(hdc);
+ SelectObject(mdc, screen_bmp);
+ BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
+ mdc, 0, 0, SRCCOPY);
+ DeleteDC(mdc);
+}
+
+static void DIB_GetWinPos(_THIS, int* px, int *py)
+{
+ RECT rect;
+ GetWindowRect(SDL_Window, &rect);
+ *px = rect.left;
+ *py = rect.top;
+}
+
+static void DIB_SetWinPos(_THIS, int x, int y)
+{
+ SetWindowPos(SDL_Window, HWND_TOPMOST,
+ x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
+}
+
+typedef struct {
+ int result;
+ int first;
+ RECT wrect;
+ RECT primary;
+} VisibilityData;
+
+
+BOOL CALLBACK visibility_cb(HMONITOR hMonitor,
+ HDC hdcMonitor,
+ LPRECT mrect,
+ LPARAM dwData)
+{
+ VisibilityData* data = (VisibilityData*)dwData;
+
+ if ( data->first ) {
+ data->first = 0;
+ data->primary = mrect[0];
+ }
+
+ if ( data->wrect.left >= mrect->left &&
+ data->wrect.right <= mrect->right &&
+ data->wrect.top >= mrect->top &&
+ data->wrect.bottom <= mrect->bottom )
+ {
+ data->result = 1;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int DIB_IsWinVisible(_THIS, int recenter)
+{
+ VisibilityData data;
+ data.result = 0;
+ data.first = 1;
+
+ GetWindowRect(SDL_Window, &data.wrect);
+
+ EnumDisplayMonitors(NULL, NULL, visibility_cb, (LPARAM)&data);
+
+ if ( !data.result && recenter ) {
+ int new_x = 10;
+ int new_y = 10;
+
+ if ( !data.first ) {
+ int primary_w = data.primary.right - data.primary.left;
+ int primary_h = data.primary.bottom - data.primary.top;
+
+ new_x = data.primary.left + (primary_w - this->screen->w)/2;
+ new_y = data.primary.top + (primary_h - this->screen->h)/2;
+ }
+ DIB_SetWinPos(this, new_x, new_y);
+ }
+ return data.result;
+}
+
+static int DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi)
+{
+ HDC displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL );
+ int xdpi, ydpi;
+
+ if (displayDC == NULL) {
+ return -1;
+ }
+ xdpi = GetDeviceCaps( displayDC, LOGPIXELSX );
+ ydpi = GetDeviceCaps( displayDC, LOGPIXELSY );
+
+ DeleteDC(displayDC);
+
+ /* sanity checks */
+ if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) {
+ return -1;
+ }
+
+ *xDpi = xdpi;
+ *yDpi = ydpi;
+ return 0;
+}
+
+
+typedef struct {
+ int first;
+ RECT wrect;
+ long bestArea;
+ RECT bestRect;
+ RECT primary;
+} ProximityData;
+
+BOOL CALLBACK proximity_cb(HMONITOR hMonitor,
+ HDC hdcMonitor,
+ LPRECT mrect,
+ LPARAM dwData)
+{
+ ProximityData* data = (ProximityData*)dwData;
+ int x1, y1, x2, y2, area;
+
+ x1 = mrect->left;
+ x2 = mrect->right;
+ y1 = mrect->top;
+ y2 = mrect->bottom;
+
+ if (data->first) {
+ data->primary = mrect[0];
+ }
+
+ if (x1 < data->wrect.left)
+ x1 = data->wrect.left;
+ if (x2 > data->wrect.right)
+ x2 = data->wrect.right;
+ if (y1 < data->wrect.top)
+ y1 = data->wrect.top;
+ if (y2 > data->wrect.bottom)
+ y2 = data->wrect.bottom;
+
+ if (x1 >= x2 || y1 >= y2)
+ return TRUE;
+
+ area = (x2-x1)*(y2-y1);
+ if (data->first || area > data->bestArea) {
+ data->first = 0;
+ data->bestRect = mrect[0];
+ data->bestArea = area;
+ }
+ return TRUE;
+}
+
+static int DIB_GetMonitorRect(_THIS, SDL_Rect* rect)
+{
+ ProximityData data;
+ RECT* sr;
+
+ data.first = 1;
+ GetWindowRect(SDL_Window, &data.wrect);
+
+ EnumDisplayMonitors(NULL, NULL, proximity_cb, (LPARAM)&data);
+
+ if (data.first)
+ return -1;
+
+ sr = &data.bestRect;
+
+ rect->x = sr->left;
+ rect->y = sr->top;
+ rect->w = sr->right - sr->left;
+ rect->h = sr->bottom - sr->top;
+
+ return 0;
+}
+
+/* Stub in case DirectX isn't available */
+#if !SDL_AUDIO_DRIVER_DSOUND
+void DX5_SoundFocus(HWND hwnd)
+{
+ return;
+}
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.h b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.h
new file mode 100644
index 0000000..48b1943
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.h
@@ -0,0 +1,59 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_dibvideo_h
+#define _SDL_dibvideo_h
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+/* Private display data */
+struct DibInfo {
+ HBITMAP screen_bmp;
+ HPALETTE screen_pal;
+ LOGPALETTE *screen_logpal;
+ BOOL grab_palette;
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+
+#ifdef _WIN32_WCE
+ int supportRotation; /* for Pocket PC devices */
+ DWORD origRotation; /* for Pocket PC devices */
+#endif
+
+ /* Screensaver settings */
+ int allow_screensaver;
+};
+/* Old variable names */
+#define screen_bmp (this->hidden->dibInfo->screen_bmp)
+#define screen_pal (this->hidden->dibInfo->screen_pal)
+#define screen_logpal (this->hidden->dibInfo->screen_logpal)
+#define grab_palette (this->hidden->dibInfo->grab_palette)
+#define SDL_nummodes (this->hidden->dibInfo->SDL_nummodes)
+#define SDL_modelist (this->hidden->dibInfo->SDL_modelist)
+#define allow_screensaver (this->hidden->dibInfo->allow_screensaver)
+
+#endif /* _SDL_dibvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_gapidibvideo.h b/distrib/sdl-1.2.15/src/video/windib/SDL_gapidibvideo.h
new file mode 100644
index 0000000..64743d1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_gapidibvideo.h
@@ -0,0 +1,56 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_gapidibvideo_h
+#define _SDL_gapidibvideo_h
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+/* typedef these to be able to define pointers, but still force everybody who
+ * wants to access them to include the corresponding header */
+typedef struct GapiInfo GapiInfo;
+typedef struct DibInfo DibInfo;
+
+/* for PDA */
+typedef enum
+{
+ SDL_ORIENTATION_UP,
+ SDL_ORIENTATION_DOWN,
+ SDL_ORIENTATION_LEFT,
+ SDL_ORIENTATION_RIGHT
+} SDL_ScreenOrientation;
+
+/* Private display data shared by gapi and windib*/
+struct SDL_PrivateVideoData {
+ int supportRotation; /* for Pocket PC devices */
+ DWORD origRotation; /* for Pocket PC devices */
+
+ GapiInfo* gapiInfo;
+ DibInfo* dibInfo;
+};
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_vkeys.h b/distrib/sdl-1.2.15/src/video/windib/SDL_vkeys.h
new file mode 100644
index 0000000..53d9246
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windib/SDL_vkeys.h
@@ -0,0 +1,75 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+#define VK_OEM_102 0xE2
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events.c b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events.c
new file mode 100644
index 0000000..e12092f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events.c
@@ -0,0 +1,1005 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* CAUTION!!!! If you modify this file, check ../windib/SDL_sysevents.c */
+
+#include "directx.h"
+
+#include "SDL_main.h"
+#include "SDL_events.h"
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "../wincommon/SDL_lowvideo.h"
+#include "SDL_dx5video.h"
+
+#ifndef WM_APP
+#define WM_APP 0x8000
+#endif
+
+#ifdef _WIN32_WCE
+#define NO_GETKEYBOARDSTATE
+#endif
+
+/* The keyboard and mouse device input */
+#define MAX_INPUTS 2
+#define INPUT_QSIZE 512 /* Buffer up to 512 input messages */
+
+static LPDIRECTINPUT dinput = NULL;
+static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
+static HANDLE SDL_DIevt[MAX_INPUTS];
+static void (*SDL_DIfun[MAX_INPUTS])(const int, DIDEVICEOBJECTDATA *);
+static int SDL_DIndev = 0;
+static int mouse_lost;
+static int mouse_pressed;
+static int mouse_buttons_swapped = 0;
+
+/* The translation table from a DirectInput scancode to an SDL keysym */
+static SDLKey DIK_keymap[256];
+static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed);
+
+/* DJM: If the user setup the window for us, we want to save his window proc,
+ and give him a chance to handle some messages. */
+#ifdef STRICT
+#define WNDPROCTYPE WNDPROC
+#else
+#define WNDPROCTYPE FARPROC
+#endif
+static WNDPROCTYPE userWindowProc = NULL;
+
+static HWND GetTopLevelParent(HWND hWnd)
+{
+ HWND hParentWnd;
+ while (1)
+ {
+ hParentWnd = GetParent(hWnd);
+ if (hParentWnd == NULL)
+ break;
+ hWnd = hParentWnd;
+ }
+ return hWnd;
+}
+
+/* Convert a DirectInput return code to a text message */
+static void SetDIerror(char *function, int code)
+{
+ static char *error;
+ static char errbuf[1024];
+
+ errbuf[0] = 0;
+ switch (code) {
+ case DIERR_GENERIC:
+ error = "Undefined error!";
+ break;
+ case DIERR_OLDDIRECTINPUTVERSION:
+ error = "Your version of DirectInput needs upgrading";
+ break;
+ case DIERR_INVALIDPARAM:
+ error = "Invalid parameters";
+ break;
+ case DIERR_OUTOFMEMORY:
+ error = "Out of memory";
+ break;
+ case DIERR_DEVICENOTREG:
+ error = "Device not registered";
+ break;
+ case DIERR_NOINTERFACE:
+ error = "Interface not supported";
+ break;
+ case DIERR_NOTINITIALIZED:
+ error = "Device not initialized";
+ break;
+ default:
+ SDL_snprintf(errbuf, SDL_arraysize(errbuf),
+ "%s: Unknown DirectInput error: 0x%x",
+ function, code);
+ break;
+ }
+ if ( ! errbuf[0] ) {
+ SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
+ }
+ SDL_SetError("%s", errbuf);
+ return;
+}
+
+/* Initialize DirectInput
+ Note: If NONEXCLUSIVE access is requested for the devices, normal
+ windows input messages will continue to be generated for that
+ input device, in addition to DirectInput messages.
+ */
+static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *events);
+static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *events);
+struct {
+ char *name;
+ REFGUID guid;
+ LPCDIDATAFORMAT format;
+ DWORD win_level;
+ DWORD raw_level;
+ void (*fun)(const int numevents, DIDEVICEOBJECTDATA *events);
+} inputs[] = {
+ { "keyboard",
+ &GUID_SysKeyboard, &c_dfDIKeyboard,
+ (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
+ (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
+ { "mouse",
+ &GUID_SysMouse,
+#if DIRECTINPUT_VERSION >= 0x700
+ &c_dfDIMouse2,
+#else
+ &c_dfDIMouse,
+#endif
+ (DISCL_BACKGROUND|DISCL_NONEXCLUSIVE),
+ (DISCL_BACKGROUND|DISCL_NONEXCLUSIVE), handle_mouse },
+ { NULL, NULL, NULL, 0, 0, NULL }
+};
+
+static int DX5_DInputInit(_THIS)
+{
+ int i;
+ LPDIRECTINPUTDEVICE device;
+ HRESULT result;
+ DIPROPDWORD dipdw;
+ HWND topwnd;
+
+ /* Create the DirectInput object */
+ result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
+ &dinput, NULL);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputCreate", result);
+ return(-1);
+ }
+
+ /* Create all of our registered input devices */
+ SDL_DIndev = 0;
+ for ( i=0; inputs[i].name; ++i ) {
+ /* Create the DirectInput device */
+ result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
+ &device, NULL);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInput::CreateDevice", result);
+ return(-1);
+ }
+ result = IDirectInputDevice_QueryInterface(device,
+ &IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
+ IDirectInputDevice_Release(device);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::QueryInterface", result);
+ return(-1);
+ }
+ topwnd = GetTopLevelParent(SDL_Window);
+ result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
+ topwnd, inputs[i].win_level);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetCooperativeLevel",
+ result);
+ return(-1);
+ }
+ result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
+ inputs[i].format);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetDataFormat", result);
+ return(-1);
+ }
+
+ /* Set buffered input -- we aren't polling */
+ SDL_memset(&dipdw, 0, sizeof(dipdw));
+ dipdw.diph.dwSize = sizeof(dipdw);
+ dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
+ dipdw.diph.dwObj = 0;
+ dipdw.diph.dwHow = DIPH_DEVICE;
+ dipdw.dwData = INPUT_QSIZE;
+ result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
+ DIPROP_BUFFERSIZE, &dipdw.diph);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetProperty", result);
+ return(-1);
+ }
+
+ /* Create an event to be signaled when input is ready */
+ SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if ( SDL_DIevt[i] == NULL ) {
+ SDL_SetError("Couldn't create DirectInput event");
+ return(-1);
+ }
+ result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
+ SDL_DIevt[i]);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetEventNotification",
+ result);
+ return(-1);
+ }
+ SDL_DIfun[i] = inputs[i].fun;
+
+ /* Acquire the device for input */
+ IDirectInputDevice2_Acquire(SDL_DIdev[i]);
+
+ /* Increment the number of devices we have */
+ ++SDL_DIndev;
+ }
+ mouse_pressed = 0;
+ mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);
+
+ /* DirectInput is ready! */
+ return(0);
+}
+
+/* Clean up DirectInput */
+static void DX5_DInputQuit(_THIS)
+{
+ int i;
+
+ if ( dinput != NULL ) {
+ /* Close and release all DirectInput devices */
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ if ( SDL_DIdev[i] != NULL ) {
+ IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
+ IDirectInputDevice2_SetEventNotification(
+ SDL_DIdev[i], NULL);
+ if ( SDL_DIevt[i] != NULL ) {
+ CloseHandle(SDL_DIevt[i]);
+ SDL_DIevt[i] = NULL;
+ }
+ IDirectInputDevice2_Release(SDL_DIdev[i]);
+ SDL_DIdev[i] = NULL;
+ }
+ }
+ SDL_DIndev = 0;
+
+ /* Release DirectInput */
+ IDirectInput_Release(dinput);
+ dinput = NULL;
+ }
+}
+
+/* Flag to tell SDL whether or not we queued an event */
+static int posted = 0;
+
+/* Input event handler functions */
+static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA *keybuf)
+{
+ int i;
+ SDL_keysym keysym;
+
+ /* Translate keyboard messages */
+ for ( i=0; i<numevents; ++i ) {
+ if ( keybuf[i].dwData & 0x80 ) {
+ posted = SDL_PrivateKeyboard(SDL_PRESSED,
+ TranslateKey(keybuf[i].dwOfs, &keysym, 1));
+ } else {
+ posted = SDL_PrivateKeyboard(SDL_RELEASED,
+ TranslateKey(keybuf[i].dwOfs, &keysym, 0));
+ }
+ }
+}
+
+static void post_mouse_motion(int relative, Sint16 x, Sint16 y)
+{
+ extern int mouse_relative;
+
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
+ posted = SDL_PrivateMouseMotion(
+ 0, relative, x, y);
+
+ if ( !mouse_relative ) {
+ /* As DirectInput reads raw device coordinates, it has no notion of
+ * cursors or absolute position. We must assume responsibility for
+ * keeping track of this. */
+ int current_x, current_y;
+ POINT cursor;
+ RECT trap;
+ RECT window;
+ int at_edge;
+
+ /* Get the current cursor position */
+ SDL_GetMouseState(&current_x, &current_y);
+ cursor.x = current_x;
+ cursor.y = current_y;
+ ClientToScreen(SDL_Window, &cursor);
+
+ /* Construct a 1 pixel square RECT that is used to confine the cursor
+ * pointer to a specific pixel using ClipCursor. This is used in
+ * preference to SetCursorPos as it avoids the cursor jumping around as
+ * both the OS and SDL attempt to move it simultaneously. */
+ trap.left = cursor.x;
+ trap.top = cursor.y;
+ trap.right = cursor.x + 1;
+ trap.bottom = cursor.y + 1;
+
+ GetClientRect(SDL_Window, &window);
+ window.right -= window.left; window.left = 0;
+ window.bottom -= window.top; window.top = 0;
+
+ /* As we're assuming control over the cursor, we need to know when to
+ * relinquish control of it back to the operating system. This is when
+ * the cursor reaches the edge of the window. */
+ at_edge = (current_x == window.left) ||
+ (current_x == (window.right - 1)) ||
+ (current_y == window.top) ||
+ (current_y == (window.bottom - 1));
+
+ if ( at_edge ) {
+ ClipCursor(NULL);
+ } else {
+ ClipCursor(&trap);
+ }
+ } else {
+ /* When in relative mode, warp the OS's idea of where the cursor is to
+ * the center of the screen. This isn't really necessary as DirectInput
+ * reads from the hardware itself, but in case things go wrong, the
+ * cursor will be left in a sensible place. */
+ POINT center;
+ center.x = (SDL_VideoSurface->w/2);
+ center.y = (SDL_VideoSurface->h/2);
+ ClientToScreen(SDL_Window, &center);
+ SetCursorPos(center.x, center.y);
+ }
+ }
+}
+
+static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
+{
+ int i;
+ Sint16 xrel, yrel;
+ Uint8 state;
+ Uint8 button;
+ DWORD timestamp = 0;
+
+ /* Sanity check. Mailing list reports this being NULL unexpectedly. */
+ if (SDL_PublicSurface == NULL) {
+ return;
+ }
+
+ /* If mouse focus has been lost, make sure we release the cursor. */
+ if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ mouse_lost = 1;
+ ClipCursor(NULL);
+ } else {
+ /* If the mouse was lost, regain some sense of mouse state */
+ if ( mouse_lost ) {
+ POINT mouse_pos;
+ Uint8 old_state;
+ Uint8 new_state;
+
+ /* Set ourselves up with the current cursor position */
+ GetCursorPos(&mouse_pos);
+ ScreenToClient(SDL_Window, &mouse_pos);
+ post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
+
+ /* Check for mouse button changes */
+ old_state = SDL_GetMouseState(NULL, NULL);
+ new_state = 0;
+ { /* Get the new DirectInput button state for the mouse */
+ #if DIRECTINPUT_VERSION >= 0x700
+ DIMOUSESTATE2 distate;
+ #else
+ DIMOUSESTATE distate;
+ #endif
+ HRESULT result;
+
+ result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
+ sizeof(distate), &distate);
+ if ( result != DI_OK ) {
+ /* Try again next time */
+ SetDIerror(
+ "IDirectInputDevice2::GetDeviceState", result);
+ return;
+ }
+ for ( i=3; i>=0; --i ) {
+ if ( (distate.rgbButtons[i]&0x80) == 0x80 ) {
+ new_state |= 0x01;
+ }
+ new_state <<= 1;
+ }
+ }
+ for ( i=0; i<8; ++i ) {
+ if ( (old_state&0x01) != (new_state&0x01) ) {
+ button = (Uint8)(i+1);
+ /* Map DI button numbers to SDL */
+ switch ( button ) {
+ case 2: button = SDL_BUTTON_RIGHT; break;
+ case 3: button = SDL_BUTTON_MIDDLE; break;
+ case 4: button = SDL_BUTTON_X1; break;
+ case 5: button = SDL_BUTTON_X2; break;
+ default: break;
+ }
+ if ( new_state & 0x01 ) {
+ /* Grab mouse so we get mouse-up */
+ if ( ++mouse_pressed > 0 ) {
+ SetCapture(SDL_Window);
+ }
+ state = SDL_PRESSED;
+ } else {
+ /* Release mouse after all mouse-ups */
+ if ( --mouse_pressed <= 0 ) {
+ ReleaseCapture();
+ mouse_pressed = 0;
+ }
+ state = SDL_RELEASED;
+ }
+ if ( mouse_buttons_swapped ) {
+ if ( button == 1 ) button = 3;
+ else
+ if ( button == 3 ) button = 1;
+ }
+ posted = SDL_PrivateMouseButton(state, button,
+ 0, 0);
+ }
+ old_state >>= 1;
+ new_state >>= 1;
+ }
+ mouse_lost = 0;
+ return;
+ }
+
+ /* Translate mouse messages */
+ xrel = 0;
+ yrel = 0;
+ for ( i=0; i<(int)numevents; ++i ) {
+ switch (ptrbuf[i].dwOfs) {
+ case DIMOFS_X:
+ if ( timestamp != ptrbuf[i].dwTimeStamp ) {
+ if ( xrel || yrel ) {
+ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+ timestamp = ptrbuf[i].dwTimeStamp;
+ }
+ xrel += (Sint16)ptrbuf[i].dwData;
+ break;
+ case DIMOFS_Y:
+ if ( timestamp != ptrbuf[i].dwTimeStamp ) {
+ if ( xrel || yrel ) {
+ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+ timestamp = ptrbuf[i].dwTimeStamp;
+ }
+ yrel += (Sint16)ptrbuf[i].dwData;
+ break;
+ case DIMOFS_Z:
+ if ( xrel || yrel ) {
+ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+ timestamp = 0;
+ if((int)ptrbuf[i].dwData > 0)
+ button = SDL_BUTTON_WHEELUP;
+ else
+ button = SDL_BUTTON_WHEELDOWN;
+ posted = SDL_PrivateMouseButton(
+ SDL_PRESSED, button, 0, 0);
+ posted |= SDL_PrivateMouseButton(
+ SDL_RELEASED, button, 0, 0);
+ break;
+ case DIMOFS_BUTTON0:
+ case DIMOFS_BUTTON1:
+ case DIMOFS_BUTTON2:
+ case DIMOFS_BUTTON3:
+ #if DIRECTINPUT_VERSION >= 0x700
+ case DIMOFS_BUTTON4:
+ case DIMOFS_BUTTON5:
+ case DIMOFS_BUTTON6:
+ case DIMOFS_BUTTON7:
+ #endif
+ if ( xrel || yrel ) {
+ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+ timestamp = 0;
+ button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
+ /* Map DI button numbers to SDL */
+ switch ( button ) {
+ case 2: button = SDL_BUTTON_RIGHT; break;
+ case 3: button = SDL_BUTTON_MIDDLE; break;
+ case 4: button = SDL_BUTTON_X1; break;
+ case 5: button = SDL_BUTTON_X2; break;
+ default: break;
+ }
+ if ( ptrbuf[i].dwData & 0x80 ) {
+ /* Grab mouse so we get mouse-up */
+ if ( ++mouse_pressed > 0 ) {
+ SetCapture(SDL_Window);
+ }
+ state = SDL_PRESSED;
+ } else {
+ /* Release mouse after all mouse-ups */
+ if ( --mouse_pressed <= 0 ) {
+ ReleaseCapture();
+ mouse_pressed = 0;
+ }
+ state = SDL_RELEASED;
+ }
+ if ( mouse_buttons_swapped ) {
+ if ( button == 1 ) button = 3;
+ else
+ if ( button == 3 ) button = 1;
+ }
+ posted = SDL_PrivateMouseButton(state, button,
+ 0, 0);
+ break;
+ }
+ }
+ if ( xrel || yrel ) {
+ post_mouse_motion(1, xrel, yrel);
+ }
+ }
+}
+
+/* The main Win32 event handler */
+LRESULT DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+#ifdef WM_ACTIVATEAPP
+ case WM_ACTIVATEAPP: {
+ int i, active;
+
+ active = (wParam && (GetForegroundWindow() == hwnd));
+ if ( active ) {
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ if (SDL_DIdev[i] != NULL)
+ IDirectInputDevice2_Acquire(
+ SDL_DIdev[i]);
+ }
+ } else {
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ if (SDL_DIdev[i] != NULL)
+ IDirectInputDevice2_Unacquire(
+ SDL_DIdev[i]);
+ }
+ mouse_lost = 1;
+ }
+ }
+ break;
+#endif /* WM_ACTIVATEAPP */
+
+#ifdef WM_DISPLAYCHANGE
+ case WM_DISPLAYCHANGE: {
+ WPARAM BitsPerPixel;
+ WORD SizeX, SizeY;
+
+ /* Ack! The display changed size and/or depth! */
+ SizeX = LOWORD(lParam);
+ SizeY = HIWORD(lParam);
+ BitsPerPixel = wParam;
+ /* We cause this message when we go fullscreen */
+ }
+ break;
+#endif /* WM_DISPLAYCHANGE */
+
+ /* The keyboard is handled via DirectInput */
+ case WM_SYSKEYUP:
+ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_KEYDOWN: {
+ /* Ignore windows keyboard messages */;
+ }
+ return(0);
+
+#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
+ /* Don't allow screen savers or monitor power downs.
+ This is because they quietly clear DirectX surfaces.
+ It would be better to allow the application to
+ decide whether or not to blow these off, but the
+ semantics of SDL_PrivateSysWMEvent() don't allow
+ the application that choice.
+ */
+ case WM_SYSCOMMAND: {
+ if ((wParam&0xFFF0)==SC_SCREENSAVE ||
+ (wParam&0xFFF0)==SC_MONITORPOWER)
+ return(0);
+ }
+ /* Fall through to default processing */
+
+#endif /* SC_SCREENSAVE || SC_MONITORPOWER */
+
+ default: {
+ /* Only post the event if we're watching for it */
+ if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.hwnd = hwnd;
+ wmmsg.msg = msg;
+ wmmsg.wParam = wParam;
+ wmmsg.lParam = lParam;
+ posted = SDL_PrivateSysWMEvent(&wmmsg);
+
+ /* DJM: If the user isn't watching for private
+ messages in her SDL event loop, then pass it
+ along to any win32 specific window proc.
+ */
+ } else if (userWindowProc) {
+ return CallWindowProc(userWindowProc, hwnd, msg, wParam, lParam);
+ }
+ }
+ break;
+ }
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+}
+
+/* This function checks the windows message queue and DirectInput and returns
+ 1 if there was input, 0 if there was no input, or -1 if the application has
+ posted a quit message.
+*/
+static int DX5_CheckInput(_THIS, int timeout, BOOL processInput)
+{
+ MSG msg;
+ int i;
+ HRESULT result;
+ DWORD event;
+
+ /* Check the normal windows queue (highest preference) */
+ posted = 0;
+ while ( ! posted &&
+ PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
+ if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
+ DispatchMessage(&msg);
+ } else {
+ return(-1);
+ }
+ }
+ if ( posted ) {
+ return(1);
+ }
+
+ /* Pump the DirectInput flow */
+ if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) {
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ if ( SDL_DIdev[i] != NULL ) {
+ result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
+ if ( (result == DIERR_INPUTLOST) ||
+ (result == DIERR_NOTACQUIRED) ) {
+ if ( SDL_strcmp(inputs[i].name, "mouse") == 0 ) {
+ mouse_lost = 1;
+ }
+ IDirectInputDevice2_Acquire(SDL_DIdev[i]);
+ IDirectInputDevice2_Poll(SDL_DIdev[i]);
+ }
+ }
+ }
+ }
+
+ /* Wait for messages and input events */
+ event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
+ timeout, QS_ALLEVENTS);
+ if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0+SDL_DIndev))) {
+ DWORD numevents;
+ static DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
+
+ event -= WAIT_OBJECT_0;
+ numevents = INPUT_QSIZE;
+ result = IDirectInputDevice2_GetDeviceData(
+ SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
+ evtbuf, &numevents, 0);
+ if ( (result == DIERR_INPUTLOST) ||
+ (result == DIERR_NOTACQUIRED) ) {
+ if ( SDL_strcmp(inputs[event].name, "mouse") == 0 ) {
+ mouse_lost = 1;
+ }
+ IDirectInputDevice2_Acquire(SDL_DIdev[event]);
+ result = IDirectInputDevice2_GetDeviceData(
+ SDL_DIdev[event], sizeof(DIDEVICEOBJECTDATA),
+ evtbuf, &numevents, 0);
+ }
+ /* Handle the events */
+ if ( result == DI_OK && processInput ) {
+ /* Note: This can post multiple events to event queue
+ */
+ (*SDL_DIfun[event])((int)numevents, evtbuf);
+ return(1);
+ }
+ }
+ if ( event != WAIT_TIMEOUT ) {
+ /* Maybe there was a windows message? */
+ if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
+ if ( GetMessage(&msg, NULL, 0, 0) > 0 ) {
+ DispatchMessage(&msg);
+ } else {
+ return(-1);
+ }
+ return(1);
+ }
+ }
+ return(0);
+}
+
+/* Change cooperative level based on whether or not we are fullscreen */
+void DX5_DInputReset(_THIS, int fullscreen)
+{
+ DWORD level;
+ int i;
+ HRESULT result;
+ HWND topwnd;
+
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ if ( SDL_DIdev[i] != NULL ) {
+ if ( fullscreen ) {
+ level = inputs[i].raw_level;
+ } else {
+ level = inputs[i].win_level;
+ }
+ IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
+ topwnd = GetTopLevelParent(SDL_Window);
+ result = IDirectInputDevice2_SetCooperativeLevel(
+ SDL_DIdev[i], topwnd, level);
+ IDirectInputDevice2_Acquire(SDL_DIdev[i]);
+ if ( result != DI_OK ) {
+ SetDIerror(
+ "DirectInputDevice::SetCooperativeLevel", result);
+ }
+ }
+ }
+ mouse_lost = 1;
+
+ /* Flush pending input */
+ DX5_CheckInput(this, 0, FALSE);
+}
+
+void DX5_PumpEvents(_THIS)
+{
+ /* Wait for messages and DirectInput */
+ while ( DX5_CheckInput(this, 0, TRUE) > 0 ) {
+ /* Loop and check again */;
+ }
+}
+
+void DX5_InitOSKeymap(_THIS)
+{
+#ifndef DIK_PAUSE
+#define DIK_PAUSE 0xC5
+#endif
+#ifndef DIK_OEM_102
+#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
+#endif
+ int i;
+
+ /* Map the DIK scancodes to SDL keysyms */
+ for ( i=0; i<SDL_arraysize(DIK_keymap); ++i )
+ DIK_keymap[i] = 0;
+
+ /* Defined DIK_* constants */
+ DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
+ DIK_keymap[DIK_1] = SDLK_1;
+ DIK_keymap[DIK_2] = SDLK_2;
+ DIK_keymap[DIK_3] = SDLK_3;
+ DIK_keymap[DIK_4] = SDLK_4;
+ DIK_keymap[DIK_5] = SDLK_5;
+ DIK_keymap[DIK_6] = SDLK_6;
+ DIK_keymap[DIK_7] = SDLK_7;
+ DIK_keymap[DIK_8] = SDLK_8;
+ DIK_keymap[DIK_9] = SDLK_9;
+ DIK_keymap[DIK_0] = SDLK_0;
+ DIK_keymap[DIK_MINUS] = SDLK_MINUS;
+ DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
+ DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
+ DIK_keymap[DIK_TAB] = SDLK_TAB;
+ DIK_keymap[DIK_Q] = SDLK_q;
+ DIK_keymap[DIK_W] = SDLK_w;
+ DIK_keymap[DIK_E] = SDLK_e;
+ DIK_keymap[DIK_R] = SDLK_r;
+ DIK_keymap[DIK_T] = SDLK_t;
+ DIK_keymap[DIK_Y] = SDLK_y;
+ DIK_keymap[DIK_U] = SDLK_u;
+ DIK_keymap[DIK_I] = SDLK_i;
+ DIK_keymap[DIK_O] = SDLK_o;
+ DIK_keymap[DIK_P] = SDLK_p;
+ DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
+ DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
+ DIK_keymap[DIK_RETURN] = SDLK_RETURN;
+ DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
+ DIK_keymap[DIK_A] = SDLK_a;
+ DIK_keymap[DIK_S] = SDLK_s;
+ DIK_keymap[DIK_D] = SDLK_d;
+ DIK_keymap[DIK_F] = SDLK_f;
+ DIK_keymap[DIK_G] = SDLK_g;
+ DIK_keymap[DIK_H] = SDLK_h;
+ DIK_keymap[DIK_J] = SDLK_j;
+ DIK_keymap[DIK_K] = SDLK_k;
+ DIK_keymap[DIK_L] = SDLK_l;
+ DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
+ DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
+ DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
+ DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
+ DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
+ DIK_keymap[DIK_OEM_102] = SDLK_LESS;
+ DIK_keymap[DIK_Z] = SDLK_z;
+ DIK_keymap[DIK_X] = SDLK_x;
+ DIK_keymap[DIK_C] = SDLK_c;
+ DIK_keymap[DIK_V] = SDLK_v;
+ DIK_keymap[DIK_B] = SDLK_b;
+ DIK_keymap[DIK_N] = SDLK_n;
+ DIK_keymap[DIK_M] = SDLK_m;
+ DIK_keymap[DIK_COMMA] = SDLK_COMMA;
+ DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
+ DIK_keymap[DIK_SLASH] = SDLK_SLASH;
+ DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
+ DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
+ DIK_keymap[DIK_LMENU] = SDLK_LALT;
+ DIK_keymap[DIK_SPACE] = SDLK_SPACE;
+ DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
+ DIK_keymap[DIK_F1] = SDLK_F1;
+ DIK_keymap[DIK_F2] = SDLK_F2;
+ DIK_keymap[DIK_F3] = SDLK_F3;
+ DIK_keymap[DIK_F4] = SDLK_F4;
+ DIK_keymap[DIK_F5] = SDLK_F5;
+ DIK_keymap[DIK_F6] = SDLK_F6;
+ DIK_keymap[DIK_F7] = SDLK_F7;
+ DIK_keymap[DIK_F8] = SDLK_F8;
+ DIK_keymap[DIK_F9] = SDLK_F9;
+ DIK_keymap[DIK_F10] = SDLK_F10;
+ DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
+ DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
+ DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
+ DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
+ DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
+ DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
+ DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
+ DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
+ DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
+ DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
+ DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
+ DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
+ DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
+ DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
+ DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
+ DIK_keymap[DIK_F11] = SDLK_F11;
+ DIK_keymap[DIK_F12] = SDLK_F12;
+
+ DIK_keymap[DIK_F13] = SDLK_F13;
+ DIK_keymap[DIK_F14] = SDLK_F14;
+ DIK_keymap[DIK_F15] = SDLK_F15;
+
+ DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
+ DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
+ DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
+ DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
+ DIK_keymap[DIK_SYSRQ] = SDLK_PRINT;
+ DIK_keymap[DIK_RMENU] = SDLK_RALT;
+ DIK_keymap[DIK_PAUSE] = SDLK_PAUSE;
+ DIK_keymap[DIK_HOME] = SDLK_HOME;
+ DIK_keymap[DIK_UP] = SDLK_UP;
+ DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
+ DIK_keymap[DIK_LEFT] = SDLK_LEFT;
+ DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
+ DIK_keymap[DIK_END] = SDLK_END;
+ DIK_keymap[DIK_DOWN] = SDLK_DOWN;
+ DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
+ DIK_keymap[DIK_INSERT] = SDLK_INSERT;
+ DIK_keymap[DIK_DELETE] = SDLK_DELETE;
+ DIK_keymap[DIK_LWIN] = SDLK_LMETA;
+ DIK_keymap[DIK_RWIN] = SDLK_RMETA;
+ DIK_keymap[DIK_APPS] = SDLK_MENU;
+}
+
+static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
+{
+ /* Set the keysym information */
+ keysym->scancode = (unsigned char)scancode;
+ keysym->sym = DIK_keymap[scancode];
+ keysym->mod = KMOD_NONE;
+ keysym->unicode = 0;
+ if ( pressed && SDL_TranslateUNICODE ) {
+ UINT vkey;
+#ifndef NO_GETKEYBOARDSTATE
+ BYTE keystate[256];
+ Uint16 wchars[2];
+#endif
+
+ vkey = MapVirtualKey(scancode, 1);
+#ifdef NO_GETKEYBOARDSTATE
+ /* Uh oh, better hope the vkey is close enough.. */
+ keysym->unicode = vkey;
+#else
+ GetKeyboardState(keystate);
+ /* Numlock isn't taken into account in ToUnicode,
+ * so we handle it as a special case here */
+ if ((keystate[VK_NUMLOCK] & 1) && vkey >= VK_NUMPAD0 && vkey <= VK_NUMPAD9)
+ {
+ keysym->unicode = vkey - VK_NUMPAD0 + '0';
+ }
+ else if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
+ {
+ keysym->unicode = wchars[0];
+ }
+#endif /* NO_GETKEYBOARDSTATE */
+ }
+ return(keysym);
+}
+
+int DX5_CreateWindow(_THIS)
+{
+ char *windowid = SDL_getenv("SDL_WINDOWID");
+ int i;
+
+ /* Clear out DirectInput variables in case we fail */
+ for ( i=0; i<MAX_INPUTS; ++i ) {
+ SDL_DIdev[i] = NULL;
+ SDL_DIevt[i] = NULL;
+ SDL_DIfun[i] = NULL;
+ }
+
+ SDL_RegisterApp(NULL, 0, 0);
+
+ SDL_windowid = (windowid != NULL);
+ if ( SDL_windowid ) {
+ SDL_Window = (HWND)((size_t)SDL_strtoull(windowid, NULL, 0));
+ if ( SDL_Window == NULL ) {
+ SDL_SetError("Couldn't get user specified window");
+ return(-1);
+ }
+
+ /* DJM: we want all event's for the user specified
+ window to be handled by SDL.
+ */
+ userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
+ SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)WinMessage);
+ } else {
+ SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
+ (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
+ CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, SDL_Instance, NULL);
+ if ( SDL_Window == NULL ) {
+ SDL_SetError("Couldn't create window");
+ return(-1);
+ }
+ ShowWindow(SDL_Window, SW_HIDE);
+ }
+
+ /* Initialize DirectInput */
+ if ( DX5_DInputInit(this) < 0 ) {
+ return(-1);
+ }
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+
+ /* Ready to roll */
+ return(0);
+}
+
+void DX5_DestroyWindow(_THIS)
+{
+ /* Close down DirectInput */
+ DX5_DInputQuit(this);
+
+ /* Destroy our window */
+ if ( SDL_windowid ) {
+ SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR)userWindowProc);
+ } else {
+ DestroyWindow(SDL_Window);
+ }
+ SDL_UnregisterApp();
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+}
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events_c.h b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events_c.h
new file mode 100644
index 0000000..28e1b6c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5events_c.h
@@ -0,0 +1,37 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "../wincommon/SDL_lowvideo.h"
+
+/* Variables and functions exported by SDL_dx5events.c to other parts
+ of the native video subsystem (SDL_dx5video.c)
+*/
+extern LONG
+ DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+extern int DX5_CreateWindow(_THIS);
+extern void DX5_DestroyWindow(_THIS);
+
+extern void DX5_PumpEvents(_THIS);
+extern void DX5_InitOSKeymap(_THIS);
+extern void DX5_DInputReset(_THIS, int fullscreen);
+
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.c b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.c
new file mode 100644
index 0000000..f80ca97
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.c
@@ -0,0 +1,2537 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "directx.h"
+
+/* Not yet in the mingw32 cross-compile headers */
+#ifndef CDS_FULLSCREEN
+#define CDS_FULLSCREEN 4
+#endif
+
+#include "SDL_timer.h"
+#include "SDL_events.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_blit.h"
+#include "../SDL_pixels_c.h"
+#include "SDL_dx5video.h"
+#include "../wincommon/SDL_syswm_c.h"
+#include "../wincommon/SDL_sysmouse_c.h"
+#include "SDL_dx5events_c.h"
+#include "SDL_dx5yuv_c.h"
+#include "../wincommon/SDL_wingl_c.h"
+
+#ifdef _WIN32_WCE
+#define NO_CHANGEDISPLAYSETTINGS
+#endif
+#ifndef WS_MAXIMIZE
+#define WS_MAXIMIZE 0
+#endif
+#ifndef SWP_NOCOPYBITS
+#define SWP_NOCOPYBITS 0
+#endif
+#ifndef PC_NOCOLLAPSE
+#define PC_NOCOLLAPSE 0
+#endif
+
+
+/* DirectX function pointers for video and events */
+HRESULT (WINAPI *DDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
+HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
+
+/* This is the rect EnumModes2 uses */
+struct DX5EnumRect {
+ SDL_Rect r;
+ int refreshRate;
+ struct DX5EnumRect* next;
+};
+static struct DX5EnumRect *enumlists[NUM_MODELISTS];
+
+/*
+ * Experimentally determined values for c_cfDI* constants used in DirectX 5.0
+ */
+
+/* Keyboard */
+
+static DIOBJECTDATAFORMAT KBD_fmt[] = {
+ { &GUID_Key, 0, 0x8000000C, 0x00000000 },
+ { &GUID_Key, 1, 0x8000010C, 0x00000000 },
+ { &GUID_Key, 2, 0x8000020C, 0x00000000 },
+ { &GUID_Key, 3, 0x8000030C, 0x00000000 },
+ { &GUID_Key, 4, 0x8000040C, 0x00000000 },
+ { &GUID_Key, 5, 0x8000050C, 0x00000000 },
+ { &GUID_Key, 6, 0x8000060C, 0x00000000 },
+ { &GUID_Key, 7, 0x8000070C, 0x00000000 },
+ { &GUID_Key, 8, 0x8000080C, 0x00000000 },
+ { &GUID_Key, 9, 0x8000090C, 0x00000000 },
+ { &GUID_Key, 10, 0x80000A0C, 0x00000000 },
+ { &GUID_Key, 11, 0x80000B0C, 0x00000000 },
+ { &GUID_Key, 12, 0x80000C0C, 0x00000000 },
+ { &GUID_Key, 13, 0x80000D0C, 0x00000000 },
+ { &GUID_Key, 14, 0x80000E0C, 0x00000000 },
+ { &GUID_Key, 15, 0x80000F0C, 0x00000000 },
+ { &GUID_Key, 16, 0x8000100C, 0x00000000 },
+ { &GUID_Key, 17, 0x8000110C, 0x00000000 },
+ { &GUID_Key, 18, 0x8000120C, 0x00000000 },
+ { &GUID_Key, 19, 0x8000130C, 0x00000000 },
+ { &GUID_Key, 20, 0x8000140C, 0x00000000 },
+ { &GUID_Key, 21, 0x8000150C, 0x00000000 },
+ { &GUID_Key, 22, 0x8000160C, 0x00000000 },
+ { &GUID_Key, 23, 0x8000170C, 0x00000000 },
+ { &GUID_Key, 24, 0x8000180C, 0x00000000 },
+ { &GUID_Key, 25, 0x8000190C, 0x00000000 },
+ { &GUID_Key, 26, 0x80001A0C, 0x00000000 },
+ { &GUID_Key, 27, 0x80001B0C, 0x00000000 },
+ { &GUID_Key, 28, 0x80001C0C, 0x00000000 },
+ { &GUID_Key, 29, 0x80001D0C, 0x00000000 },
+ { &GUID_Key, 30, 0x80001E0C, 0x00000000 },
+ { &GUID_Key, 31, 0x80001F0C, 0x00000000 },
+ { &GUID_Key, 32, 0x8000200C, 0x00000000 },
+ { &GUID_Key, 33, 0x8000210C, 0x00000000 },
+ { &GUID_Key, 34, 0x8000220C, 0x00000000 },
+ { &GUID_Key, 35, 0x8000230C, 0x00000000 },
+ { &GUID_Key, 36, 0x8000240C, 0x00000000 },
+ { &GUID_Key, 37, 0x8000250C, 0x00000000 },
+ { &GUID_Key, 38, 0x8000260C, 0x00000000 },
+ { &GUID_Key, 39, 0x8000270C, 0x00000000 },
+ { &GUID_Key, 40, 0x8000280C, 0x00000000 },
+ { &GUID_Key, 41, 0x8000290C, 0x00000000 },
+ { &GUID_Key, 42, 0x80002A0C, 0x00000000 },
+ { &GUID_Key, 43, 0x80002B0C, 0x00000000 },
+ { &GUID_Key, 44, 0x80002C0C, 0x00000000 },
+ { &GUID_Key, 45, 0x80002D0C, 0x00000000 },
+ { &GUID_Key, 46, 0x80002E0C, 0x00000000 },
+ { &GUID_Key, 47, 0x80002F0C, 0x00000000 },
+ { &GUID_Key, 48, 0x8000300C, 0x00000000 },
+ { &GUID_Key, 49, 0x8000310C, 0x00000000 },
+ { &GUID_Key, 50, 0x8000320C, 0x00000000 },
+ { &GUID_Key, 51, 0x8000330C, 0x00000000 },
+ { &GUID_Key, 52, 0x8000340C, 0x00000000 },
+ { &GUID_Key, 53, 0x8000350C, 0x00000000 },
+ { &GUID_Key, 54, 0x8000360C, 0x00000000 },
+ { &GUID_Key, 55, 0x8000370C, 0x00000000 },
+ { &GUID_Key, 56, 0x8000380C, 0x00000000 },
+ { &GUID_Key, 57, 0x8000390C, 0x00000000 },
+ { &GUID_Key, 58, 0x80003A0C, 0x00000000 },
+ { &GUID_Key, 59, 0x80003B0C, 0x00000000 },
+ { &GUID_Key, 60, 0x80003C0C, 0x00000000 },
+ { &GUID_Key, 61, 0x80003D0C, 0x00000000 },
+ { &GUID_Key, 62, 0x80003E0C, 0x00000000 },
+ { &GUID_Key, 63, 0x80003F0C, 0x00000000 },
+ { &GUID_Key, 64, 0x8000400C, 0x00000000 },
+ { &GUID_Key, 65, 0x8000410C, 0x00000000 },
+ { &GUID_Key, 66, 0x8000420C, 0x00000000 },
+ { &GUID_Key, 67, 0x8000430C, 0x00000000 },
+ { &GUID_Key, 68, 0x8000440C, 0x00000000 },
+ { &GUID_Key, 69, 0x8000450C, 0x00000000 },
+ { &GUID_Key, 70, 0x8000460C, 0x00000000 },
+ { &GUID_Key, 71, 0x8000470C, 0x00000000 },
+ { &GUID_Key, 72, 0x8000480C, 0x00000000 },
+ { &GUID_Key, 73, 0x8000490C, 0x00000000 },
+ { &GUID_Key, 74, 0x80004A0C, 0x00000000 },
+ { &GUID_Key, 75, 0x80004B0C, 0x00000000 },
+ { &GUID_Key, 76, 0x80004C0C, 0x00000000 },
+ { &GUID_Key, 77, 0x80004D0C, 0x00000000 },
+ { &GUID_Key, 78, 0x80004E0C, 0x00000000 },
+ { &GUID_Key, 79, 0x80004F0C, 0x00000000 },
+ { &GUID_Key, 80, 0x8000500C, 0x00000000 },
+ { &GUID_Key, 81, 0x8000510C, 0x00000000 },
+ { &GUID_Key, 82, 0x8000520C, 0x00000000 },
+ { &GUID_Key, 83, 0x8000530C, 0x00000000 },
+ { &GUID_Key, 84, 0x8000540C, 0x00000000 },
+ { &GUID_Key, 85, 0x8000550C, 0x00000000 },
+ { &GUID_Key, 86, 0x8000560C, 0x00000000 },
+ { &GUID_Key, 87, 0x8000570C, 0x00000000 },
+ { &GUID_Key, 88, 0x8000580C, 0x00000000 },
+ { &GUID_Key, 89, 0x8000590C, 0x00000000 },
+ { &GUID_Key, 90, 0x80005A0C, 0x00000000 },
+ { &GUID_Key, 91, 0x80005B0C, 0x00000000 },
+ { &GUID_Key, 92, 0x80005C0C, 0x00000000 },
+ { &GUID_Key, 93, 0x80005D0C, 0x00000000 },
+ { &GUID_Key, 94, 0x80005E0C, 0x00000000 },
+ { &GUID_Key, 95, 0x80005F0C, 0x00000000 },
+ { &GUID_Key, 96, 0x8000600C, 0x00000000 },
+ { &GUID_Key, 97, 0x8000610C, 0x00000000 },
+ { &GUID_Key, 98, 0x8000620C, 0x00000000 },
+ { &GUID_Key, 99, 0x8000630C, 0x00000000 },
+ { &GUID_Key, 100, 0x8000640C, 0x00000000 },
+ { &GUID_Key, 101, 0x8000650C, 0x00000000 },
+ { &GUID_Key, 102, 0x8000660C, 0x00000000 },
+ { &GUID_Key, 103, 0x8000670C, 0x00000000 },
+ { &GUID_Key, 104, 0x8000680C, 0x00000000 },
+ { &GUID_Key, 105, 0x8000690C, 0x00000000 },
+ { &GUID_Key, 106, 0x80006A0C, 0x00000000 },
+ { &GUID_Key, 107, 0x80006B0C, 0x00000000 },
+ { &GUID_Key, 108, 0x80006C0C, 0x00000000 },
+ { &GUID_Key, 109, 0x80006D0C, 0x00000000 },
+ { &GUID_Key, 110, 0x80006E0C, 0x00000000 },
+ { &GUID_Key, 111, 0x80006F0C, 0x00000000 },
+ { &GUID_Key, 112, 0x8000700C, 0x00000000 },
+ { &GUID_Key, 113, 0x8000710C, 0x00000000 },
+ { &GUID_Key, 114, 0x8000720C, 0x00000000 },
+ { &GUID_Key, 115, 0x8000730C, 0x00000000 },
+ { &GUID_Key, 116, 0x8000740C, 0x00000000 },
+ { &GUID_Key, 117, 0x8000750C, 0x00000000 },
+ { &GUID_Key, 118, 0x8000760C, 0x00000000 },
+ { &GUID_Key, 119, 0x8000770C, 0x00000000 },
+ { &GUID_Key, 120, 0x8000780C, 0x00000000 },
+ { &GUID_Key, 121, 0x8000790C, 0x00000000 },
+ { &GUID_Key, 122, 0x80007A0C, 0x00000000 },
+ { &GUID_Key, 123, 0x80007B0C, 0x00000000 },
+ { &GUID_Key, 124, 0x80007C0C, 0x00000000 },
+ { &GUID_Key, 125, 0x80007D0C, 0x00000000 },
+ { &GUID_Key, 126, 0x80007E0C, 0x00000000 },
+ { &GUID_Key, 127, 0x80007F0C, 0x00000000 },
+ { &GUID_Key, 128, 0x8000800C, 0x00000000 },
+ { &GUID_Key, 129, 0x8000810C, 0x00000000 },
+ { &GUID_Key, 130, 0x8000820C, 0x00000000 },
+ { &GUID_Key, 131, 0x8000830C, 0x00000000 },
+ { &GUID_Key, 132, 0x8000840C, 0x00000000 },
+ { &GUID_Key, 133, 0x8000850C, 0x00000000 },
+ { &GUID_Key, 134, 0x8000860C, 0x00000000 },
+ { &GUID_Key, 135, 0x8000870C, 0x00000000 },
+ { &GUID_Key, 136, 0x8000880C, 0x00000000 },
+ { &GUID_Key, 137, 0x8000890C, 0x00000000 },
+ { &GUID_Key, 138, 0x80008A0C, 0x00000000 },
+ { &GUID_Key, 139, 0x80008B0C, 0x00000000 },
+ { &GUID_Key, 140, 0x80008C0C, 0x00000000 },
+ { &GUID_Key, 141, 0x80008D0C, 0x00000000 },
+ { &GUID_Key, 142, 0x80008E0C, 0x00000000 },
+ { &GUID_Key, 143, 0x80008F0C, 0x00000000 },
+ { &GUID_Key, 144, 0x8000900C, 0x00000000 },
+ { &GUID_Key, 145, 0x8000910C, 0x00000000 },
+ { &GUID_Key, 146, 0x8000920C, 0x00000000 },
+ { &GUID_Key, 147, 0x8000930C, 0x00000000 },
+ { &GUID_Key, 148, 0x8000940C, 0x00000000 },
+ { &GUID_Key, 149, 0x8000950C, 0x00000000 },
+ { &GUID_Key, 150, 0x8000960C, 0x00000000 },
+ { &GUID_Key, 151, 0x8000970C, 0x00000000 },
+ { &GUID_Key, 152, 0x8000980C, 0x00000000 },
+ { &GUID_Key, 153, 0x8000990C, 0x00000000 },
+ { &GUID_Key, 154, 0x80009A0C, 0x00000000 },
+ { &GUID_Key, 155, 0x80009B0C, 0x00000000 },
+ { &GUID_Key, 156, 0x80009C0C, 0x00000000 },
+ { &GUID_Key, 157, 0x80009D0C, 0x00000000 },
+ { &GUID_Key, 158, 0x80009E0C, 0x00000000 },
+ { &GUID_Key, 159, 0x80009F0C, 0x00000000 },
+ { &GUID_Key, 160, 0x8000A00C, 0x00000000 },
+ { &GUID_Key, 161, 0x8000A10C, 0x00000000 },
+ { &GUID_Key, 162, 0x8000A20C, 0x00000000 },
+ { &GUID_Key, 163, 0x8000A30C, 0x00000000 },
+ { &GUID_Key, 164, 0x8000A40C, 0x00000000 },
+ { &GUID_Key, 165, 0x8000A50C, 0x00000000 },
+ { &GUID_Key, 166, 0x8000A60C, 0x00000000 },
+ { &GUID_Key, 167, 0x8000A70C, 0x00000000 },
+ { &GUID_Key, 168, 0x8000A80C, 0x00000000 },
+ { &GUID_Key, 169, 0x8000A90C, 0x00000000 },
+ { &GUID_Key, 170, 0x8000AA0C, 0x00000000 },
+ { &GUID_Key, 171, 0x8000AB0C, 0x00000000 },
+ { &GUID_Key, 172, 0x8000AC0C, 0x00000000 },
+ { &GUID_Key, 173, 0x8000AD0C, 0x00000000 },
+ { &GUID_Key, 174, 0x8000AE0C, 0x00000000 },
+ { &GUID_Key, 175, 0x8000AF0C, 0x00000000 },
+ { &GUID_Key, 176, 0x8000B00C, 0x00000000 },
+ { &GUID_Key, 177, 0x8000B10C, 0x00000000 },
+ { &GUID_Key, 178, 0x8000B20C, 0x00000000 },
+ { &GUID_Key, 179, 0x8000B30C, 0x00000000 },
+ { &GUID_Key, 180, 0x8000B40C, 0x00000000 },
+ { &GUID_Key, 181, 0x8000B50C, 0x00000000 },
+ { &GUID_Key, 182, 0x8000B60C, 0x00000000 },
+ { &GUID_Key, 183, 0x8000B70C, 0x00000000 },
+ { &GUID_Key, 184, 0x8000B80C, 0x00000000 },
+ { &GUID_Key, 185, 0x8000B90C, 0x00000000 },
+ { &GUID_Key, 186, 0x8000BA0C, 0x00000000 },
+ { &GUID_Key, 187, 0x8000BB0C, 0x00000000 },
+ { &GUID_Key, 188, 0x8000BC0C, 0x00000000 },
+ { &GUID_Key, 189, 0x8000BD0C, 0x00000000 },
+ { &GUID_Key, 190, 0x8000BE0C, 0x00000000 },
+ { &GUID_Key, 191, 0x8000BF0C, 0x00000000 },
+ { &GUID_Key, 192, 0x8000C00C, 0x00000000 },
+ { &GUID_Key, 193, 0x8000C10C, 0x00000000 },
+ { &GUID_Key, 194, 0x8000C20C, 0x00000000 },
+ { &GUID_Key, 195, 0x8000C30C, 0x00000000 },
+ { &GUID_Key, 196, 0x8000C40C, 0x00000000 },
+ { &GUID_Key, 197, 0x8000C50C, 0x00000000 },
+ { &GUID_Key, 198, 0x8000C60C, 0x00000000 },
+ { &GUID_Key, 199, 0x8000C70C, 0x00000000 },
+ { &GUID_Key, 200, 0x8000C80C, 0x00000000 },
+ { &GUID_Key, 201, 0x8000C90C, 0x00000000 },
+ { &GUID_Key, 202, 0x8000CA0C, 0x00000000 },
+ { &GUID_Key, 203, 0x8000CB0C, 0x00000000 },
+ { &GUID_Key, 204, 0x8000CC0C, 0x00000000 },
+ { &GUID_Key, 205, 0x8000CD0C, 0x00000000 },
+ { &GUID_Key, 206, 0x8000CE0C, 0x00000000 },
+ { &GUID_Key, 207, 0x8000CF0C, 0x00000000 },
+ { &GUID_Key, 208, 0x8000D00C, 0x00000000 },
+ { &GUID_Key, 209, 0x8000D10C, 0x00000000 },
+ { &GUID_Key, 210, 0x8000D20C, 0x00000000 },
+ { &GUID_Key, 211, 0x8000D30C, 0x00000000 },
+ { &GUID_Key, 212, 0x8000D40C, 0x00000000 },
+ { &GUID_Key, 213, 0x8000D50C, 0x00000000 },
+ { &GUID_Key, 214, 0x8000D60C, 0x00000000 },
+ { &GUID_Key, 215, 0x8000D70C, 0x00000000 },
+ { &GUID_Key, 216, 0x8000D80C, 0x00000000 },
+ { &GUID_Key, 217, 0x8000D90C, 0x00000000 },
+ { &GUID_Key, 218, 0x8000DA0C, 0x00000000 },
+ { &GUID_Key, 219, 0x8000DB0C, 0x00000000 },
+ { &GUID_Key, 220, 0x8000DC0C, 0x00000000 },
+ { &GUID_Key, 221, 0x8000DD0C, 0x00000000 },
+ { &GUID_Key, 222, 0x8000DE0C, 0x00000000 },
+ { &GUID_Key, 223, 0x8000DF0C, 0x00000000 },
+ { &GUID_Key, 224, 0x8000E00C, 0x00000000 },
+ { &GUID_Key, 225, 0x8000E10C, 0x00000000 },
+ { &GUID_Key, 226, 0x8000E20C, 0x00000000 },
+ { &GUID_Key, 227, 0x8000E30C, 0x00000000 },
+ { &GUID_Key, 228, 0x8000E40C, 0x00000000 },
+ { &GUID_Key, 229, 0x8000E50C, 0x00000000 },
+ { &GUID_Key, 230, 0x8000E60C, 0x00000000 },
+ { &GUID_Key, 231, 0x8000E70C, 0x00000000 },
+ { &GUID_Key, 232, 0x8000E80C, 0x00000000 },
+ { &GUID_Key, 233, 0x8000E90C, 0x00000000 },
+ { &GUID_Key, 234, 0x8000EA0C, 0x00000000 },
+ { &GUID_Key, 235, 0x8000EB0C, 0x00000000 },
+ { &GUID_Key, 236, 0x8000EC0C, 0x00000000 },
+ { &GUID_Key, 237, 0x8000ED0C, 0x00000000 },
+ { &GUID_Key, 238, 0x8000EE0C, 0x00000000 },
+ { &GUID_Key, 239, 0x8000EF0C, 0x00000000 },
+ { &GUID_Key, 240, 0x8000F00C, 0x00000000 },
+ { &GUID_Key, 241, 0x8000F10C, 0x00000000 },
+ { &GUID_Key, 242, 0x8000F20C, 0x00000000 },
+ { &GUID_Key, 243, 0x8000F30C, 0x00000000 },
+ { &GUID_Key, 244, 0x8000F40C, 0x00000000 },
+ { &GUID_Key, 245, 0x8000F50C, 0x00000000 },
+ { &GUID_Key, 246, 0x8000F60C, 0x00000000 },
+ { &GUID_Key, 247, 0x8000F70C, 0x00000000 },
+ { &GUID_Key, 248, 0x8000F80C, 0x00000000 },
+ { &GUID_Key, 249, 0x8000F90C, 0x00000000 },
+ { &GUID_Key, 250, 0x8000FA0C, 0x00000000 },
+ { &GUID_Key, 251, 0x8000FB0C, 0x00000000 },
+ { &GUID_Key, 252, 0x8000FC0C, 0x00000000 },
+ { &GUID_Key, 253, 0x8000FD0C, 0x00000000 },
+ { &GUID_Key, 254, 0x8000FE0C, 0x00000000 },
+ { &GUID_Key, 255, 0x8000FF0C, 0x00000000 },
+};
+
+const DIDATAFORMAT c_dfDIKeyboard = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 256, 256, KBD_fmt };
+
+
+/* Mouse */
+
+static DIOBJECTDATAFORMAT PTR_fmt[] = {
+ { &GUID_XAxis, 0, 0x00FFFF03, 0x00000000 },
+ { &GUID_YAxis, 4, 0x00FFFF03, 0x00000000 },
+ { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000000 },
+ { NULL, 12, 0x00FFFF0C, 0x00000000 },
+ { NULL, 13, 0x00FFFF0C, 0x00000000 },
+ { NULL, 14, 0x80FFFF0C, 0x00000000 },
+ { NULL, 15, 0x80FFFF0C, 0x00000000 },
+};
+
+const DIDATAFORMAT c_dfDIMouse = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 16, 7, PTR_fmt };
+
+static DIOBJECTDATAFORMAT PTR2_fmt[] = {
+ { &GUID_XAxis, 0, 0x00FFFF03, 0x00000000 },
+ { &GUID_YAxis, 4, 0x00FFFF03, 0x00000000 },
+ { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000000 },
+ { NULL, 12, 0x00FFFF0C, 0x00000000 },
+ { NULL, 13, 0x00FFFF0C, 0x00000000 },
+ { NULL, 14, 0x80FFFF0C, 0x00000000 },
+ { NULL, 15, 0x80FFFF0C, 0x00000000 },
+ { NULL, 16, 0x80FFFF0C, 0x00000000 },
+ { NULL, 17, 0x80FFFF0C, 0x00000000 },
+ { NULL, 18, 0x80FFFF0C, 0x00000000 },
+ { NULL, 19, 0x80FFFF0C, 0x00000000 }
+};
+
+const DIDATAFORMAT c_dfDIMouse2 = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000002, 20, 11, PTR2_fmt };
+
+
+/* Joystick */
+
+static DIOBJECTDATAFORMAT JOY_fmt[] = {
+ { &GUID_XAxis, 0, 0x80FFFF03, 0x00000100 },
+ { &GUID_YAxis, 4, 0x80FFFF03, 0x00000100 },
+ { &GUID_ZAxis, 8, 0x80FFFF03, 0x00000100 },
+ { &GUID_RxAxis, 12, 0x80FFFF03, 0x00000100 },
+ { &GUID_RyAxis, 16, 0x80FFFF03, 0x00000100 },
+ { &GUID_RzAxis, 20, 0x80FFFF03, 0x00000100 },
+ { &GUID_Slider, 24, 0x80FFFF03, 0x00000100 },
+ { &GUID_Slider, 28, 0x80FFFF03, 0x00000100 },
+ { &GUID_POV, 32, 0x80FFFF10, 0x00000000 },
+ { &GUID_POV, 36, 0x80FFFF10, 0x00000000 },
+ { &GUID_POV, 40, 0x80FFFF10, 0x00000000 },
+ { &GUID_POV, 44, 0x80FFFF10, 0x00000000 },
+ { NULL, 48, 0x80FFFF0C, 0x00000000 },
+ { NULL, 49, 0x80FFFF0C, 0x00000000 },
+ { NULL, 50, 0x80FFFF0C, 0x00000000 },
+ { NULL, 51, 0x80FFFF0C, 0x00000000 },
+ { NULL, 52, 0x80FFFF0C, 0x00000000 },
+ { NULL, 53, 0x80FFFF0C, 0x00000000 },
+ { NULL, 54, 0x80FFFF0C, 0x00000000 },
+ { NULL, 55, 0x80FFFF0C, 0x00000000 },
+ { NULL, 56, 0x80FFFF0C, 0x00000000 },
+ { NULL, 57, 0x80FFFF0C, 0x00000000 },
+ { NULL, 58, 0x80FFFF0C, 0x00000000 },
+ { NULL, 59, 0x80FFFF0C, 0x00000000 },
+ { NULL, 60, 0x80FFFF0C, 0x00000000 },
+ { NULL, 61, 0x80FFFF0C, 0x00000000 },
+ { NULL, 62, 0x80FFFF0C, 0x00000000 },
+ { NULL, 63, 0x80FFFF0C, 0x00000000 },
+ { NULL, 64, 0x80FFFF0C, 0x00000000 },
+ { NULL, 65, 0x80FFFF0C, 0x00000000 },
+ { NULL, 66, 0x80FFFF0C, 0x00000000 },
+ { NULL, 67, 0x80FFFF0C, 0x00000000 },
+ { NULL, 68, 0x80FFFF0C, 0x00000000 },
+ { NULL, 69, 0x80FFFF0C, 0x00000000 },
+ { NULL, 70, 0x80FFFF0C, 0x00000000 },
+ { NULL, 71, 0x80FFFF0C, 0x00000000 },
+ { NULL, 72, 0x80FFFF0C, 0x00000000 },
+ { NULL, 73, 0x80FFFF0C, 0x00000000 },
+ { NULL, 74, 0x80FFFF0C, 0x00000000 },
+ { NULL, 75, 0x80FFFF0C, 0x00000000 },
+ { NULL, 76, 0x80FFFF0C, 0x00000000 },
+ { NULL, 77, 0x80FFFF0C, 0x00000000 },
+ { NULL, 78, 0x80FFFF0C, 0x00000000 },
+ { NULL, 79, 0x80FFFF0C, 0x00000000 },
+};
+
+const DIDATAFORMAT c_dfDIJoystick = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), 0x00000001, 80, 44, JOY_fmt };
+
+
+/* Initialization/Query functions */
+static int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **DX5_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int DX5_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static int DX5_SetGammaRamp(_THIS, Uint16 *ramp);
+static int DX5_GetGammaRamp(_THIS, Uint16 *ramp);
+static void DX5_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int DX5_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int DX5_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
+static int DX5_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
+static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
+static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
+static int DX5_LockHWSurface(_THIS, SDL_Surface *surface);
+static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void DX5_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface,
+ LPDIRECTDRAWSURFACE3 requested, Uint32 flag);
+
+/* Windows message handling functions */
+static void DX5_Activate(_THIS, BOOL active, BOOL minimized);
+static void DX5_RealizePalette(_THIS);
+static void DX5_PaletteChanged(_THIS, HWND window);
+static void DX5_WinPAINT(_THIS, HDC hdc);
+
+/* WinDIB driver functions for manipulating gamma ramps */
+extern int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
+extern int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
+extern void DIB_QuitGamma(_THIS);
+
+/* DX5 driver bootstrap functions */
+
+static int DX5_Available(void)
+{
+ HINSTANCE DInputDLL;
+ HINSTANCE DDrawDLL;
+ int dinput_ok;
+ int ddraw_ok;
+
+ /* Version check DINPUT.DLL and DDRAW.DLL (Is DirectX okay?) */
+ dinput_ok = 0;
+ DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
+ if ( DInputDLL != NULL ) {
+ dinput_ok = 1;
+ FreeLibrary(DInputDLL);
+ }
+ ddraw_ok = 0;
+ DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
+ if ( DDrawDLL != NULL ) {
+ HRESULT (WINAPI *DDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
+ LPDIRECTDRAW DDraw;
+
+ /* Try to create a valid DirectDraw object */
+ DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));
+ if ( (DDrawCreate != NULL)
+ && !FAILED(DDrawCreate(NULL, &DDraw, NULL)) ) {
+ if ( !FAILED(IDirectDraw_SetCooperativeLevel(DDraw,
+ NULL, DDSCL_NORMAL)) ) {
+ DDSURFACEDESC desc;
+ LPDIRECTDRAWSURFACE DDrawSurf;
+ LPDIRECTDRAWSURFACE3 DDrawSurf3;
+
+ /* Try to create a DirectDrawSurface3 object */
+ SDL_memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY;
+ if ( !FAILED(IDirectDraw_CreateSurface(DDraw, &desc,
+ &DDrawSurf, NULL)) ) {
+ if ( !FAILED(IDirectDrawSurface_QueryInterface(DDrawSurf,
+ &IID_IDirectDrawSurface3, (LPVOID *)&DDrawSurf3)) ) {
+ /* Yay! */
+ ddraw_ok = 1;
+
+ /* Clean up.. */
+ IDirectDrawSurface3_Release(DDrawSurf3);
+ }
+ IDirectDrawSurface_Release(DDrawSurf);
+ }
+ }
+ IDirectDraw_Release(DDraw);
+ }
+ FreeLibrary(DDrawDLL);
+ }
+ return(dinput_ok && ddraw_ok);
+}
+
+/* Functions for loading the DirectX functions dynamically */
+static HINSTANCE DDrawDLL = NULL;
+static HINSTANCE DInputDLL = NULL;
+
+static void DX5_Unload(void)
+{
+ if ( DDrawDLL != NULL ) {
+ FreeLibrary(DDrawDLL);
+ DDrawCreate = NULL;
+ DDrawDLL = NULL;
+ }
+ if ( DInputDLL != NULL ) {
+ FreeLibrary(DInputDLL);
+ DInputCreate = NULL;
+ DInputDLL = NULL;
+ }
+}
+static int DX5_Load(void)
+{
+ int status;
+
+ DX5_Unload();
+ DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
+ if ( DDrawDLL != NULL ) {
+ DDrawCreate = (void *)GetProcAddress(DDrawDLL,
+ TEXT("DirectDrawCreate"));
+ }
+ DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
+ if ( DInputDLL != NULL ) {
+ DInputCreate = (void *)GetProcAddress(DInputDLL,
+ TEXT("DirectInputCreateA"));
+ }
+ if ( DDrawDLL && DDrawCreate && DInputDLL && DInputCreate ) {
+ status = 0;
+ } else {
+ DX5_Unload();
+ status = -1;
+ }
+ return status;
+}
+
+static void DX5_DeleteDevice(SDL_VideoDevice *this)
+{
+ /* Free DirectDraw object */
+ if ( ddraw2 != NULL ) {
+ IDirectDraw2_Release(ddraw2);
+ }
+ DX5_Unload();
+ if ( this ) {
+ if ( this->hidden ) {
+ SDL_free(this->hidden);
+ }
+ if ( this->gl_data ) {
+ SDL_free(this->gl_data);
+ }
+ SDL_free(this);
+ }
+}
+
+static SDL_VideoDevice *DX5_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Load DirectX */
+ if ( DX5_Load() < 0 ) {
+ return(NULL);
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ device->gl_data = (struct SDL_PrivateGLData *)
+ SDL_malloc((sizeof *device->gl_data));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ||
+ (device->gl_data == NULL) ) {
+ SDL_OutOfMemory();
+ DX5_DeleteDevice(device);
+ return(NULL);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
+
+ /* Set the function pointers */
+ device->VideoInit = DX5_VideoInit;
+ device->ListModes = DX5_ListModes;
+ device->SetVideoMode = DX5_SetVideoMode;
+ device->UpdateMouse = WIN_UpdateMouse;
+ device->CreateYUVOverlay = DX5_CreateYUVOverlay;
+ device->SetColors = DX5_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = DX5_VideoQuit;
+ device->AllocHWSurface = DX5_AllocHWSurface;
+ device->CheckHWBlit = DX5_CheckHWBlit;
+ device->FillHWRect = DX5_FillHWRect;
+ device->SetHWColorKey = DX5_SetHWColorKey;
+ device->SetHWAlpha = DX5_SetHWAlpha;
+ device->LockHWSurface = DX5_LockHWSurface;
+ device->UnlockHWSurface = DX5_UnlockHWSurface;
+ device->FlipHWSurface = DX5_FlipHWSurface;
+ device->FreeHWSurface = DX5_FreeHWSurface;
+ device->SetGammaRamp = DX5_SetGammaRamp;
+ device->GetGammaRamp = DX5_GetGammaRamp;
+#if SDL_VIDEO_OPENGL
+ device->GL_LoadLibrary = WIN_GL_LoadLibrary;
+ device->GL_GetProcAddress = WIN_GL_GetProcAddress;
+ device->GL_GetAttribute = WIN_GL_GetAttribute;
+ device->GL_MakeCurrent = WIN_GL_MakeCurrent;
+ device->GL_SwapBuffers = WIN_GL_SwapBuffers;
+#endif
+ device->SetCaption = WIN_SetWMCaption;
+ device->SetIcon = WIN_SetWMIcon;
+ device->IconifyWindow = WIN_IconifyWindow;
+ device->GrabInput = WIN_GrabInput;
+ device->GetWMInfo = WIN_GetWMInfo;
+ device->FreeWMCursor = WIN_FreeWMCursor;
+ device->CreateWMCursor = WIN_CreateWMCursor;
+ device->ShowWMCursor = WIN_ShowWMCursor;
+ device->WarpWMCursor = WIN_WarpWMCursor;
+ device->CheckMouseMode = WIN_CheckMouseMode;
+ device->InitOSKeymap = DX5_InitOSKeymap;
+ device->PumpEvents = DX5_PumpEvents;
+
+ /* Set up the windows message handling functions */
+ WIN_Activate = DX5_Activate;
+ WIN_RealizePalette = DX5_RealizePalette;
+ WIN_PaletteChanged = DX5_PaletteChanged;
+ WIN_WinPAINT = DX5_WinPAINT;
+ HandleMessage = DX5_HandleMessage;
+
+ device->free = DX5_DeleteDevice;
+
+ /* We're finally ready */
+ return device;
+}
+
+VideoBootStrap DIRECTX_bootstrap = {
+ "directx", "Win95/98/2000 DirectX",
+ DX5_Available, DX5_CreateDevice
+};
+
+static int cmpmodes(const void *va, const void *vb)
+{
+ SDL_Rect *a = *(SDL_Rect **)va;
+ SDL_Rect *b = *(SDL_Rect **)vb;
+ if ( a->w == b->w )
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+
+static HRESULT WINAPI EnumModes2(DDSURFACEDESC *desc, VOID *udata)
+{
+ SDL_VideoDevice *this = (SDL_VideoDevice *)udata;
+ struct DX5EnumRect *enumrect;
+#if defined(NONAMELESSUNION)
+ int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
+ int refreshRate = desc->u2.dwRefreshRate;
+#else
+ int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
+ int refreshRate = desc->dwRefreshRate;
+#endif
+ int maxRefreshRate;
+
+ if ( desc->dwWidth <= SDL_desktop_mode.dmPelsWidth &&
+ desc->dwHeight <= SDL_desktop_mode.dmPelsHeight ) {
+ maxRefreshRate = SDL_desktop_mode.dmDisplayFrequency;
+ } else {
+ maxRefreshRate = 85; /* safe value? */
+ }
+
+ switch (bpp) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ bpp /= 8; --bpp;
+ if ( enumlists[bpp] &&
+ enumlists[bpp]->r.w == (Uint16)desc->dwWidth &&
+ enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) {
+ if ( refreshRate > enumlists[bpp]->refreshRate &&
+ refreshRate <= maxRefreshRate ) {
+ enumlists[bpp]->refreshRate = refreshRate;
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
+#endif
+ }
+ break;
+ }
+ ++SDL_nummodes[bpp];
+ enumrect = (struct DX5EnumRect*)SDL_malloc(sizeof(struct DX5EnumRect));
+ if ( !enumrect ) {
+ SDL_OutOfMemory();
+ return(DDENUMRET_CANCEL);
+ }
+ enumrect->refreshRate = refreshRate;
+ enumrect->r.x = 0;
+ enumrect->r.y = 0;
+ enumrect->r.w = (Uint16)desc->dwWidth;
+ enumrect->r.h = (Uint16)desc->dwHeight;
+ enumrect->next = enumlists[bpp];
+ enumlists[bpp] = enumrect;
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
+#endif
+ break;
+ }
+
+ return(DDENUMRET_OK);
+}
+
+void SetDDerror(const char *function, int code)
+{
+ static char *error;
+ static char errbuf[1024];
+
+ errbuf[0] = 0;
+ switch (code) {
+ case DDERR_GENERIC:
+ error = "Undefined error!";
+ break;
+ case DDERR_EXCEPTION:
+ error = "Exception encountered";
+ break;
+ case DDERR_INVALIDOBJECT:
+ error = "Invalid object";
+ break;
+ case DDERR_INVALIDPARAMS:
+ error = "Invalid parameters";
+ break;
+ case DDERR_NOTFOUND:
+ error = "Object not found";
+ break;
+ case DDERR_INVALIDRECT:
+ error = "Invalid rectangle";
+ break;
+ case DDERR_INVALIDCAPS:
+ error = "Invalid caps member";
+ break;
+ case DDERR_INVALIDPIXELFORMAT:
+ error = "Invalid pixel format";
+ break;
+ case DDERR_OUTOFMEMORY:
+ error = "Out of memory";
+ break;
+ case DDERR_OUTOFVIDEOMEMORY:
+ error = "Out of video memory";
+ break;
+ case DDERR_SURFACEBUSY:
+ error = "Surface busy";
+ break;
+ case DDERR_SURFACELOST:
+ error = "Surface was lost";
+ break;
+ case DDERR_WASSTILLDRAWING:
+ error = "DirectDraw is still drawing";
+ break;
+ case DDERR_INVALIDSURFACETYPE:
+ error = "Invalid surface type";
+ break;
+ case DDERR_NOEXCLUSIVEMODE:
+ error = "Not in exclusive access mode";
+ break;
+ case DDERR_NOPALETTEATTACHED:
+ error = "No palette attached";
+ break;
+ case DDERR_NOPALETTEHW:
+ error = "No palette hardware";
+ break;
+ case DDERR_NOT8BITCOLOR:
+ error = "Not 8-bit color";
+ break;
+ case DDERR_EXCLUSIVEMODEALREADYSET:
+ error = "Exclusive mode was already set";
+ break;
+ case DDERR_HWNDALREADYSET:
+ error = "Window handle already set";
+ break;
+ case DDERR_HWNDSUBCLASSED:
+ error = "Window handle is subclassed";
+ break;
+ case DDERR_NOBLTHW:
+ error = "No blit hardware";
+ break;
+ case DDERR_IMPLICITLYCREATED:
+ error = "Surface was implicitly created";
+ break;
+ case DDERR_INCOMPATIBLEPRIMARY:
+ error = "Incompatible primary surface";
+ break;
+ case DDERR_NOCOOPERATIVELEVELSET:
+ error = "No cooperative level set";
+ break;
+ case DDERR_NODIRECTDRAWHW:
+ error = "No DirectDraw hardware";
+ break;
+ case DDERR_NOEMULATION:
+ error = "No emulation available";
+ break;
+ case DDERR_NOFLIPHW:
+ error = "No flip hardware";
+ break;
+ case DDERR_NOTFLIPPABLE:
+ error = "Surface not flippable";
+ break;
+ case DDERR_PRIMARYSURFACEALREADYEXISTS:
+ error = "Primary surface already exists";
+ break;
+ case DDERR_UNSUPPORTEDMODE:
+ error = "Unsupported mode";
+ break;
+ case DDERR_WRONGMODE:
+ error = "Surface created in different mode";
+ break;
+ case DDERR_UNSUPPORTED:
+ error = "Operation not supported";
+ break;
+ case E_NOINTERFACE:
+ error = "Interface not present";
+ break;
+ default:
+ SDL_snprintf(errbuf, SDL_arraysize(errbuf),
+ "%s: Unknown DirectDraw error: 0x%x",
+ function, code);
+ break;
+ }
+ if ( ! errbuf[0] ) {
+ SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error);
+ }
+ SDL_SetError("%s", errbuf);
+ return;
+}
+
+
+static int DX5_UpdateVideoInfo(_THIS)
+{
+ /* This needs to be DDCAPS_DX5 for the DirectDraw2 interface */
+#if DIRECTDRAW_VERSION <= 0x300
+#error Your version of DirectX must be greater than or equal to 5.0
+#endif
+#ifndef IDirectDrawGammaControl_SetGammaRamp
+ /*if gamma is undefined then we really have directx <= 0x500*/
+ DDCAPS DDCaps;
+#else
+ DDCAPS_DX5 DDCaps;
+#endif
+ HRESULT result;
+
+ /* Fill in our hardware acceleration capabilities */
+ SDL_memset(&DDCaps, 0, sizeof(DDCaps));
+ DDCaps.dwSize = sizeof(DDCaps);
+ result = IDirectDraw2_GetCaps(ddraw2, (DDCAPS *)&DDCaps, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::GetCaps", result);
+ return(-1);
+ }
+ this->info.hw_available = 1;
+ if ( (DDCaps.dwCaps & DDCAPS_BLT) == DDCAPS_BLT ) {
+ this->info.blit_hw = 1;
+ }
+ if ( ((DDCaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) &&
+ ((DDCaps.dwCKeyCaps & DDCKEYCAPS_SRCBLT) == DDCKEYCAPS_SRCBLT) ) {
+ this->info.blit_hw_CC = 1;
+ }
+ if ( (DDCaps.dwCaps & DDCAPS_ALPHA) == DDCAPS_ALPHA ) {
+ /* This is only for alpha channel, and DirectX 6
+ doesn't support 2D alpha blits yet, so set it 0
+ */
+ this->info.blit_hw_A = 0;
+ }
+ if ( (DDCaps.dwCaps & DDCAPS_CANBLTSYSMEM) == DDCAPS_CANBLTSYSMEM ) {
+ this->info.blit_sw = 1;
+ /* This isn't necessarily true, but the HEL will cover us */
+ this->info.blit_sw_CC = this->info.blit_hw_CC;
+ this->info.blit_sw_A = this->info.blit_hw_A;
+ }
+ if ( (DDCaps.dwCaps & DDCAPS_BLTCOLORFILL) == DDCAPS_BLTCOLORFILL ) {
+ this->info.blit_fill = 1;
+ }
+
+ /* Find out how much video memory is available */
+ { DDSCAPS ddsCaps;
+ DWORD total_mem;
+ ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
+ result = IDirectDraw2_GetAvailableVidMem(ddraw2,
+ &ddsCaps, &total_mem, NULL);
+ if ( result != DD_OK ) {
+ total_mem = DDCaps.dwVidMemTotal;
+ }
+ this->info.video_mem = total_mem/1024;
+ }
+ return(0);
+}
+
+int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ HRESULT result;
+ LPDIRECTDRAW ddraw;
+ int i, j;
+ HDC hdc;
+
+ /* Intialize everything */
+ ddraw2 = NULL;
+ SDL_primary = NULL;
+ SDL_clipper = NULL;
+ SDL_palette = NULL;
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_nummodes[i] = 0;
+ SDL_modelist[i] = NULL;
+ SDL_modeindex[i] = 0;
+ }
+ colorchange_expected = 0;
+
+ /* Create the window */
+ if ( DX5_CreateWindow(this) < 0 ) {
+ return(-1);
+ }
+
+#if !SDL_AUDIO_DISABLED
+ DX5_SoundFocus(SDL_Window);
+#endif
+
+ /* Create the DirectDraw object */
+ result = DDrawCreate(NULL, &ddraw, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawCreate", result);
+ return(-1);
+ }
+ result = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw2,
+ (LPVOID *)&ddraw2);
+ IDirectDraw_Release(ddraw);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw::QueryInterface", result);
+ return(-1);
+ }
+
+ /* Determine the screen depth */
+ hdc = GetDC(SDL_Window);
+ vformat->BitsPerPixel = GetDeviceCaps(hdc,PLANES) *
+ GetDeviceCaps(hdc,BITSPIXEL);
+ ReleaseDC(SDL_Window, hdc);
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ /* Query for the desktop resolution */
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
+ this->info.current_w = SDL_desktop_mode.dmPelsWidth;
+ this->info.current_h = SDL_desktop_mode.dmPelsHeight;
+#endif
+
+ /* Enumerate the available fullscreen modes */
+ for ( i=0; i<NUM_MODELISTS; ++i )
+ enumlists[i] = NULL;
+
+ result = IDirectDraw2_EnumDisplayModes(ddraw2,DDEDM_REFRESHRATES,NULL,this,EnumModes2);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::EnumDisplayModes", result);
+ return(-1);
+ }
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ struct DX5EnumRect *rect;
+ SDL_modelist[i] = (SDL_Rect **)
+ SDL_malloc((SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[i] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) {
+ SDL_modelist[i][j] = &rect->r;
+ }
+ SDL_modelist[i][j] = NULL;
+
+ if ( SDL_nummodes[i] > 0 ) {
+ SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
+ }
+ }
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ /* Fill in the video hardware capabilities */
+ DX5_UpdateVideoInfo(this);
+
+ return(0);
+}
+
+SDL_Rect **DX5_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ int bpp;
+
+ bpp = format->BitsPerPixel;
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ /* FIXME: No support for 1 bpp or 4 bpp formats */
+ switch (bpp) { /* Does windows support other BPP? */
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ bpp = (bpp/8)-1;
+ if ( SDL_nummodes[bpp] > 0 )
+ return(SDL_modelist[bpp]);
+ /* Fall through */
+ default:
+ return((SDL_Rect **)0);
+ }
+ } else {
+ if ( this->screen->format->BitsPerPixel == bpp ) {
+ return((SDL_Rect **)-1);
+ } else {
+ return((SDL_Rect **)0);
+ }
+ }
+}
+
+/* Various screen update functions available */
+static void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ SDL_Surface *video;
+ int prev_w = -1;
+ int prev_h = -1;
+ HRESULT result;
+ DWORD sharemode;
+ DWORD style;
+ const DWORD directstyle =
+ (WS_POPUP);
+ const DWORD windowstyle =
+ (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
+ const DWORD resizestyle =
+ (WS_THICKFRAME|WS_MAXIMIZEBOX);
+ DDSURFACEDESC ddsd;
+ LPDIRECTDRAWSURFACE dd_surface1;
+ LPDIRECTDRAWSURFACE3 dd_surface3;
+
+ SDL_resizing = 1;
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "Setting %dx%dx%d video mode\n", width, height, bpp);
+#endif
+ /* Clean up any previous DirectDraw surfaces */
+ if ( current->hwdata ) {
+ this->FreeHWSurface(this, current);
+ current->hwdata = NULL;
+ }
+ if ( SDL_primary != NULL ) {
+ IDirectDrawSurface3_Release(SDL_primary);
+ SDL_primary = NULL;
+ }
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ /* Unset any previous OpenGL fullscreen mode */
+ if ( (current->flags & (SDL_OPENGL|SDL_FULLSCREEN)) ==
+ (SDL_OPENGL|SDL_FULLSCREEN) ) {
+ ChangeDisplaySettings(NULL, 0);
+ }
+#endif
+
+ /* Clean up any GL context that may be hanging around */
+ if ( current->flags & SDL_OPENGL ) {
+ WIN_GL_ShutDown(this);
+ }
+
+ /* If we are setting a GL mode, use GDI, not DirectX (yuck) */
+ if ( flags & SDL_OPENGL ) {
+ Uint32 Rmask, Gmask, Bmask;
+
+ /* Recalculate the bitmasks if necessary */
+ if ( bpp == current->format->BitsPerPixel ) {
+ video = current;
+ } else {
+ switch (bpp) {
+ case 15:
+ case 16:
+ if ( 0 /*DIB_SussScreenDepth() == 15*/ ) {
+ /* 5-5-5 */
+ Rmask = 0x00007c00;
+ Gmask = 0x000003e0;
+ Bmask = 0x0000001f;
+ } else {
+ /* 5-6-5 */
+ Rmask = 0x0000f800;
+ Gmask = 0x000007e0;
+ Bmask = 0x0000001f;
+ }
+ break;
+ case 24:
+ case 32:
+ /* GDI defined as 8-8-8 */
+ Rmask = 0x00ff0000;
+ Gmask = 0x0000ff00;
+ Bmask = 0x000000ff;
+ break;
+ default:
+ Rmask = 0x00000000;
+ Gmask = 0x00000000;
+ Bmask = 0x00000000;
+ break;
+ }
+ video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, bpp,
+ Rmask, Gmask, Bmask, 0);
+ if ( video == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ }
+
+ /* Fill in part of the video surface */
+ prev_w = video->w;
+ prev_h = video->h;
+ video->flags = 0; /* Clear flags */
+ video->w = width;
+ video->h = height;
+ video->pitch = SDL_CalculatePitch(video);
+
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ /* Set fullscreen mode if appropriate.
+ Ugh, since our list of valid video modes comes from
+ the DirectX driver, we may not actually be able to
+ change to the desired resolution here.
+ FIXME: Should we do a closest match?
+ */
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ DEVMODE settings;
+ BOOL changed;
+
+ SDL_memset(&settings, 0, sizeof(DEVMODE));
+ settings.dmSize = sizeof(DEVMODE);
+ settings.dmBitsPerPel = video->format->BitsPerPixel;
+ settings.dmPelsWidth = width;
+ settings.dmPelsHeight = height;
+ settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
+ if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
+ height <= (int)SDL_desktop_mode.dmPelsHeight ) {
+ settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
+ settings.dmFields |= DM_DISPLAYFREQUENCY;
+ }
+ changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
+ if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
+ settings.dmFields &= ~DM_DISPLAYFREQUENCY;
+ changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
+ }
+ if ( changed ) {
+ video->flags |= SDL_FULLSCREEN;
+ SDL_fullscreen_mode = settings;
+ }
+ }
+#endif /* !NO_CHANGEDISPLAYSETTINGS */
+
+ style = GetWindowLong(SDL_Window, GWL_STYLE);
+ style &= ~(resizestyle|WS_MAXIMIZE);
+ if ( video->flags & SDL_FULLSCREEN ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ } else {
+ if ( flags & SDL_NOFRAME ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ video->flags |= SDL_NOFRAME;
+ } else {
+ style &= ~directstyle;
+ style |= windowstyle;
+ if ( flags & SDL_RESIZABLE ) {
+ style |= resizestyle;
+ video->flags |= SDL_RESIZABLE;
+ }
+ }
+#if WS_MAXIMIZE
+ if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+ }
+
+ /* DJM: Don't piss of anyone who has setup his own window */
+ if ( !SDL_windowid )
+ SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+ /* Resize the window (copied from SDL WinDIB driver) */
+ if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
+ RECT bounds;
+ int x, y;
+ HWND top;
+ UINT swp_flags;
+ const char *window = NULL;
+ const char *center = NULL;
+
+ if ( video->w != prev_w || video->h != prev_h ) {
+ window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
+ center = SDL_getenv("SDL_VIDEO_CENTERED");
+ if ( window ) {
+ if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
+ SDL_windowX = x;
+ SDL_windowY = y;
+ }
+ if ( SDL_strcmp(window, "center") == 0 ) {
+ center = window;
+ }
+ }
+ }
+ swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
+
+ bounds.left = SDL_windowX;
+ bounds.top = SDL_windowY;
+ bounds.right = SDL_windowX+video->w;
+ bounds.bottom = SDL_windowY+video->h;
+ AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
+ width = bounds.right-bounds.left;
+ height = bounds.bottom-bounds.top;
+ if ( (flags & SDL_FULLSCREEN) ) {
+ x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ } else if ( center ) {
+ x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ } else if ( SDL_windowX || SDL_windowY || window ) {
+ x = bounds.left;
+ y = bounds.top;
+ } else {
+ x = y = -1;
+ swp_flags |= SWP_NOMOVE;
+ }
+ if ( flags & SDL_FULLSCREEN ) {
+ top = HWND_TOPMOST;
+ } else {
+ top = HWND_NOTOPMOST;
+ }
+ SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
+ if ( !(flags & SDL_FULLSCREEN) ) {
+ SDL_windowX = SDL_bounds.left;
+ SDL_windowY = SDL_bounds.top;
+ }
+ SetForegroundWindow(SDL_Window);
+ }
+ SDL_resizing = 0;
+
+ /* Set up for OpenGL */
+ if ( WIN_GL_SetupWindow(this) < 0 ) {
+ return(NULL);
+ }
+ video->flags |= SDL_OPENGL;
+ return(video);
+ }
+
+ /* Set the appropriate window style */
+ style = GetWindowLong(SDL_Window, GWL_STYLE);
+ style &= ~(resizestyle|WS_MAXIMIZE);
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ } else {
+ if ( flags & SDL_NOFRAME ) {
+ style &= ~windowstyle;
+ style |= directstyle;
+ } else {
+ style &= ~directstyle;
+ style |= windowstyle;
+ if ( flags & SDL_RESIZABLE ) {
+ style |= resizestyle;
+ }
+ }
+#if WS_MAXIMIZE
+ if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
+#endif
+ }
+ /* DJM: Don't piss of anyone who has setup his own window */
+ if ( !SDL_windowid )
+ SetWindowLong(SDL_Window, GWL_STYLE, style);
+
+ /* Set DirectDraw sharing mode.. exclusive when fullscreen */
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ sharemode = DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT;
+ } else {
+ sharemode = DDSCL_NORMAL;
+ }
+ result = IDirectDraw2_SetCooperativeLevel(ddraw2,SDL_Window,sharemode);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::SetCooperativeLevel", result);
+ return(NULL);
+ }
+
+ /* Set the display mode, if we are in fullscreen mode */
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ RECT bounds;
+ struct DX5EnumRect *rect;
+ int maxRefreshRate;
+
+ /* Cover up desktop during mode change */
+ bounds.left = 0;
+ bounds.top = 0;
+ bounds.right = GetSystemMetrics(SM_CXSCREEN);
+ bounds.bottom = GetSystemMetrics(SM_CYSCREEN);
+ AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
+ SetWindowPos(SDL_Window, HWND_TOPMOST,
+ bounds.left, bounds.top,
+ bounds.right - bounds.left,
+ bounds.bottom - bounds.top, SWP_NOCOPYBITS);
+ ShowWindow(SDL_Window, SW_SHOW);
+ while ( GetForegroundWindow() != SDL_Window ) {
+ SetForegroundWindow(SDL_Window);
+ SDL_Delay(100);
+ }
+
+ /* find maximum monitor refresh rate for this resolution */
+ /* Dmitry Yakimov ftech@tula.net */
+ maxRefreshRate = 0; /* system default */
+ for ( rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next ) {
+ if ( (width == rect->r.w) && (height == rect->r.h) ) {
+ maxRefreshRate = rect->refreshRate;
+ break;
+ }
+ }
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "refresh rate = %d Hz\n", maxRefreshRate);
+#endif
+
+ result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, maxRefreshRate, 0);
+ if ( result != DD_OK ) {
+ result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0);
+ if ( result != DD_OK ) {
+ /* We couldn't set fullscreen mode, try window */
+ return(DX5_SetVideoMode(this, current, width, height, bpp, flags & ~SDL_FULLSCREEN));
+ }
+ }
+ DX5_DInputReset(this, 1);
+ } else {
+ DX5_DInputReset(this, 0);
+ }
+ DX5_UpdateVideoInfo(this);
+
+ /* Create a primary DirectDraw surface */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY);
+ if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
+ /* There's no windowed double-buffering */
+ flags &= ~SDL_DOUBLEBUF;
+ }
+ if ( (flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
+ ddsd.ddsCaps.dwCaps |= (DDSCAPS_COMPLEX|DDSCAPS_FLIP);
+ ddsd.dwBackBufferCount = 1;
+ }
+ result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
+ if ( (result != DD_OK) && ((flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) ) {
+ ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+ ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX|DDSCAPS_FLIP);
+ ddsd.dwBackBufferCount = 0;
+ result = IDirectDraw2_CreateSurface(ddraw2,
+ &ddsd, &dd_surface1, NULL);
+ }
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::CreateSurface(PRIMARY)", result);
+ return(NULL);
+ }
+ result = IDirectDrawSurface_QueryInterface(dd_surface1,
+ &IID_IDirectDrawSurface3, (LPVOID *)&SDL_primary);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface::QueryInterface", result);
+ return(NULL);
+ }
+ IDirectDrawSurface_Release(dd_surface1);
+
+ /* Get the format of the primary DirectDraw surface */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_PIXELFORMAT|DDSD_CAPS;
+ result = IDirectDrawSurface3_GetSurfaceDesc(SDL_primary, &ddsd);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface::GetSurfaceDesc", result);
+ return(NULL);
+ }
+ if ( ! (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) ) {
+ SDL_SetError("Primary DDRAW surface is not RGB format");
+ return(NULL);
+ }
+
+ /* Free old palette and create a new one if we're in 8-bit mode */
+ if ( SDL_palette != NULL ) {
+ IDirectDrawPalette_Release(SDL_palette);
+ SDL_palette = NULL;
+ }
+#if defined(NONAMELESSUNION)
+ if ( ddsd.ddpfPixelFormat.u1.dwRGBBitCount == 8 ) {
+#else
+ if ( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) {
+#endif
+ int i;
+
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ /* We have access to the entire palette */
+ for ( i=0; i<256; ++i ) {
+ SDL_colors[i].peFlags =
+ (PC_NOCOLLAPSE|PC_RESERVED);
+ SDL_colors[i].peRed = 0;
+ SDL_colors[i].peGreen = 0;
+ SDL_colors[i].peBlue = 0;
+ }
+ } else {
+ /* First 10 colors are reserved by Windows */
+ for ( i=0; i<10; ++i ) {
+ SDL_colors[i].peFlags = PC_EXPLICIT;
+ SDL_colors[i].peRed = i;
+ SDL_colors[i].peGreen = 0;
+ SDL_colors[i].peBlue = 0;
+ }
+ for ( i=10; i<(10+236); ++i ) {
+ SDL_colors[i].peFlags = PC_NOCOLLAPSE;
+ SDL_colors[i].peRed = 0;
+ SDL_colors[i].peGreen = 0;
+ SDL_colors[i].peBlue = 0;
+ }
+ /* Last 10 colors are reserved by Windows */
+ for ( i=246; i<256; ++i ) {
+ SDL_colors[i].peFlags = PC_EXPLICIT;
+ SDL_colors[i].peRed = i;
+ SDL_colors[i].peGreen = 0;
+ SDL_colors[i].peBlue = 0;
+ }
+ }
+ result = IDirectDraw2_CreatePalette(ddraw2,
+ (DDPCAPS_8BIT|DDPCAPS_ALLOW256),
+ SDL_colors, &SDL_palette, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::CreatePalette", result);
+ return(NULL);
+ }
+ result = IDirectDrawSurface3_SetPalette(SDL_primary,
+ SDL_palette);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::SetPalette", result);
+ return(NULL);
+ }
+ }
+
+ /* Create our video surface using the same pixel format */
+ video = current;
+ if ( (width != video->w) || (height != video->h)
+ || (video->format->BitsPerPixel !=
+#if defined(NONAMELESSUNION)
+ ddsd.ddpfPixelFormat.u1.dwRGBBitCount) ) {
+#else
+ ddsd.ddpfPixelFormat.dwRGBBitCount) ) {
+#endif
+ SDL_FreeSurface(video);
+ video = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0,
+#if defined(NONAMELESSUNION)
+ ddsd.ddpfPixelFormat.u1.dwRGBBitCount,
+ ddsd.ddpfPixelFormat.u2.dwRBitMask,
+ ddsd.ddpfPixelFormat.u3.dwGBitMask,
+ ddsd.ddpfPixelFormat.u4.dwBBitMask,
+#else
+ ddsd.ddpfPixelFormat.dwRGBBitCount,
+ ddsd.ddpfPixelFormat.dwRBitMask,
+ ddsd.ddpfPixelFormat.dwGBitMask,
+ ddsd.ddpfPixelFormat.dwBBitMask,
+#endif
+ 0);
+ if ( video == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ prev_w = video->w;
+ prev_h = video->h;
+ video->w = width;
+ video->h = height;
+ video->pitch = 0;
+ }
+ video->flags = 0; /* Clear flags */
+
+ /* If not fullscreen, locking is possible, but it doesn't do what
+ the caller really expects -- if the locked surface is written to,
+ the appropriate portion of the entire screen is modified, not
+ the application window, as we would like.
+ Note that it is still possible to write directly to display
+ memory, but the application must respect the clip list of
+ the surface. There might be some odd timing interactions
+ involving clip list updates and background refreshing as
+ Windows moves other windows across our window.
+ We currently don't support this, even though it might be a
+ good idea since BeOS has an implementation of BDirectWindow
+ that does the same thing. This would be most useful for
+ applications that do complete screen updates every frame.
+ -- Fixme?
+ */
+ if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
+ /* Necessary if we're going from fullscreen to window */
+ if ( video->pixels == NULL ) {
+ video->pitch = (width*video->format->BytesPerPixel);
+ /* Pitch needs to be QWORD (8-byte) aligned */
+ video->pitch = (video->pitch + 7) & ~7;
+ video->pixels = (void *)SDL_malloc(video->h*video->pitch);
+ if ( video->pixels == NULL ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ }
+ dd_surface3 = NULL;
+#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */
+ if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ video->flags |= SDL_HWSURFACE;
+ } else {
+ video->flags |= SDL_SWSURFACE;
+ }
+#else
+ video->flags |= SDL_SWSURFACE;
+#endif
+ if ( (flags & SDL_RESIZABLE) && !(flags & SDL_NOFRAME) ) {
+ video->flags |= SDL_RESIZABLE;
+ }
+ if ( flags & SDL_NOFRAME ) {
+ video->flags |= SDL_NOFRAME;
+ }
+ } else {
+ /* Necessary if we're going from window to fullscreen */
+ if ( video->pixels != NULL ) {
+ SDL_free(video->pixels);
+ video->pixels = NULL;
+ }
+ dd_surface3 = SDL_primary;
+ video->flags |= SDL_HWSURFACE;
+ }
+
+ /* See if the primary surface has double-buffering enabled */
+ if ( (ddsd.ddsCaps.dwCaps & DDSCAPS_FLIP) == DDSCAPS_FLIP ) {
+ video->flags |= SDL_DOUBLEBUF;
+ }
+
+ /* Allocate the SDL surface associated with the primary surface */
+ if ( DX5_AllocDDSurface(this, video, dd_surface3,
+ video->flags&SDL_HWSURFACE) < 0 ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ return(NULL);
+ }
+
+ /* Use the appropriate blitting function */
+ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ video->flags |= SDL_FULLSCREEN;
+ if ( video->format->palette != NULL ) {
+ video->flags |= SDL_HWPALETTE;
+ }
+ this->UpdateRects = DX5_DirectUpdate;
+ } else {
+ this->UpdateRects = DX5_WindowUpdate;
+ }
+
+ /* Make our window the proper size, set the clipper, then show it */
+ if ( (flags & SDL_FULLSCREEN) != SDL_FULLSCREEN ) {
+ /* Create and set a clipper on our primary surface */
+ if ( SDL_clipper == NULL ) {
+ result = IDirectDraw2_CreateClipper(ddraw2,
+ 0, &SDL_clipper, NULL);
+ if ( result != DD_OK ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SetDDerror("DirectDraw2::CreateClipper",result);
+ return(NULL);
+ }
+ }
+ result = IDirectDrawClipper_SetHWnd(SDL_clipper, 0, SDL_Window);
+ if ( result != DD_OK ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SetDDerror("DirectDrawClipper::SetHWnd", result);
+ return(NULL);
+ }
+ result = IDirectDrawSurface3_SetClipper(SDL_primary,
+ SDL_clipper);
+ if ( result != DD_OK ) {
+ if ( video != current ) {
+ SDL_FreeSurface(video);
+ }
+ SetDDerror("DirectDrawSurface3::SetClipper", result);
+ return(NULL);
+ }
+
+ /* Resize the window (copied from SDL WinDIB driver) */
+ if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
+ RECT bounds;
+ int x, y;
+ UINT swp_flags;
+ const char *window = NULL;
+ const char *center = NULL;
+
+ if ( video->w != prev_w || video->h != prev_h ) {
+ window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
+ center = SDL_getenv("SDL_VIDEO_CENTERED");
+ if ( window ) {
+ if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
+ SDL_windowX = x;
+ SDL_windowY = y;
+ }
+ if ( SDL_strcmp(window, "center") == 0 ) {
+ center = window;
+ }
+ }
+ }
+ swp_flags = SWP_NOCOPYBITS;
+
+ bounds.left = SDL_windowX;
+ bounds.top = SDL_windowY;
+ bounds.right = SDL_windowX+video->w;
+ bounds.bottom = SDL_windowY+video->h;
+ AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
+ width = bounds.right-bounds.left;
+ height = bounds.bottom-bounds.top;
+ if ( center ) {
+ x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ } else if ( SDL_windowX || SDL_windowY || window ) {
+ x = bounds.left;
+ y = bounds.top;
+ } else {
+ x = y = -1;
+ swp_flags |= SWP_NOMOVE;
+ }
+ SetWindowPos(SDL_Window, HWND_NOTOPMOST, x, y, width, height, swp_flags);
+ SDL_windowX = SDL_bounds.left;
+ SDL_windowY = SDL_bounds.top;
+ }
+
+ }
+ ShowWindow(SDL_Window, SW_SHOW);
+ SetForegroundWindow(SDL_Window);
+ SDL_resizing = 0;
+
+ /* JC 14 Mar 2006
+ Flush the message loop or this can cause big problems later
+ Especially if the user decides to use dialog boxes or assert()!
+ */
+ WIN_FlushMessageQueue();
+
+ /* We're live! */
+ return(video);
+}
+
+struct private_hwdata {
+ LPDIRECTDRAWSURFACE3 dd_surface;
+ LPDIRECTDRAWSURFACE3 dd_writebuf;
+};
+
+static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface,
+ LPDIRECTDRAWSURFACE3 requested, Uint32 flag)
+{
+ LPDIRECTDRAWSURFACE dd_surface1;
+ LPDIRECTDRAWSURFACE3 dd_surface3;
+ DDSURFACEDESC ddsd;
+ HRESULT result;
+
+ /* Clear the hardware flag, in case we fail */
+ surface->flags &= ~flag;
+
+ /* Allocate the hardware acceleration data */
+ surface->hwdata = (struct private_hwdata *)
+ SDL_malloc(sizeof(*surface->hwdata));
+ if ( surface->hwdata == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ dd_surface3 = NULL;
+
+ /* Set up the surface description */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|
+ DDSD_PITCH|DDSD_PIXELFORMAT);
+ ddsd.dwWidth = surface->w;
+ ddsd.dwHeight= surface->h;
+#if defined(NONAMELESSUNION)
+ ddsd.u1.lPitch = surface->pitch;
+#else
+ ddsd.lPitch = surface->pitch;
+#endif
+ if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ ddsd.ddsCaps.dwCaps =
+ (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);
+ } else {
+ ddsd.ddsCaps.dwCaps =
+ (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);
+ }
+ ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+ if ( surface->format->palette ) {
+ ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
+ }
+#if defined(NONAMELESSUNION)
+ ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel;
+ ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask;
+ ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask;
+ ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask;
+#else
+ ddsd.ddpfPixelFormat.dwRGBBitCount = surface->format->BitsPerPixel;
+ ddsd.ddpfPixelFormat.dwRBitMask = surface->format->Rmask;
+ ddsd.ddpfPixelFormat.dwGBitMask = surface->format->Gmask;
+ ddsd.ddpfPixelFormat.dwBBitMask = surface->format->Bmask;
+#endif
+
+ /* Create the DirectDraw video surface */
+ if ( requested != NULL ) {
+ dd_surface3 = requested;
+ } else {
+ result = IDirectDraw2_CreateSurface(ddraw2,
+ &ddsd, &dd_surface1, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::CreateSurface", result);
+ goto error_end;
+ }
+ result = IDirectDrawSurface_QueryInterface(dd_surface1,
+ &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);
+ IDirectDrawSurface_Release(dd_surface1);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface::QueryInterface", result);
+ goto error_end;
+ }
+ }
+
+ if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ /* Check to see whether the surface actually ended up
+ in video memory, and fail if not. We expect the
+ surfaces we create here to actually be in hardware!
+ */
+ result = IDirectDrawSurface3_GetCaps(dd_surface3,&ddsd.ddsCaps);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::GetCaps", result);
+ goto error_end;
+ }
+ if ( (ddsd.ddsCaps.dwCaps&DDSCAPS_VIDEOMEMORY) !=
+ DDSCAPS_VIDEOMEMORY ) {
+ SDL_SetError("No room in video memory");
+ goto error_end;
+ }
+ } else {
+ /* Try to hook our surface memory */
+ ddsd.dwFlags = DDSD_LPSURFACE;
+ ddsd.lpSurface = surface->pixels;
+ result = IDirectDrawSurface3_SetSurfaceDesc(dd_surface3,
+ &ddsd, 0);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::SetSurfaceDesc", result);
+ goto error_end;
+ }
+
+ }
+
+ /* Make sure the surface format was set properly */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
+ &ddsd, (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Lock", result);
+ goto error_end;
+ }
+ IDirectDrawSurface3_Unlock(dd_surface3, NULL);
+
+ if ( (flag & SDL_HWSURFACE) == SDL_SWSURFACE ) {
+ if ( ddsd.lpSurface != surface->pixels ) {
+ SDL_SetError("DDraw didn't use SDL surface memory");
+ goto error_end;
+ }
+ if (
+#if defined(NONAMELESSUNION)
+ ddsd.u1.lPitch
+#else
+ ddsd.lPitch
+#endif
+ != (LONG)surface->pitch ) {
+ SDL_SetError("DDraw created surface with wrong pitch");
+ goto error_end;
+ }
+ } else {
+#if defined(NONAMELESSUNION)
+ surface->pitch = (Uint16)ddsd.u1.lPitch;
+#else
+ surface->pitch = (Uint16)ddsd.lPitch;
+#endif
+ }
+#if defined(NONAMELESSUNION)
+ if ( (ddsd.ddpfPixelFormat.u1.dwRGBBitCount !=
+ surface->format->BitsPerPixel) ||
+ (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) ||
+ (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) ||
+ (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask) ){
+#else
+ if ( (ddsd.ddpfPixelFormat.dwRGBBitCount !=
+ surface->format->BitsPerPixel) ||
+ (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) ||
+ (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) ||
+ (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask) ){
+#endif
+ SDL_SetError("DDraw didn't use SDL surface description");
+ goto error_end;
+ }
+ if ( (ddsd.dwWidth != (DWORD)surface->w) ||
+ (ddsd.dwHeight != (DWORD)surface->h) ) {
+ SDL_SetError("DDraw created surface with wrong size");
+ goto error_end;
+ }
+
+ /* Set the surface private data */
+ surface->flags |= flag;
+ surface->hwdata->dd_surface = dd_surface3;
+ if ( (surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
+ LPDIRECTDRAWSURFACE3 dd_writebuf;
+
+ ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
+ result = IDirectDrawSurface3_GetAttachedSurface(dd_surface3,
+ &ddsd.ddsCaps, &dd_writebuf);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::GetAttachedSurface",
+ result);
+ } else {
+ dd_surface3 = dd_writebuf;
+ }
+ }
+ surface->hwdata->dd_writebuf = dd_surface3;
+
+ /* We're ready to go! */
+ return(0);
+
+ /* Okay, so goto's are cheesy, but there are so many possible
+ errors in this function, and the cleanup is the same in
+ every single case. Is there a better way, other than deeply
+ nesting the code?
+ */
+error_end:
+ if ( (dd_surface3 != NULL) && (dd_surface3 != requested) ) {
+ IDirectDrawSurface_Release(dd_surface3);
+ }
+ SDL_free(surface->hwdata);
+ surface->hwdata = NULL;
+ return(-1);
+}
+
+static int DX5_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ /* DDraw limitation -- you need to set cooperative level first */
+ if ( SDL_primary == NULL ) {
+ SDL_SetError("You must set a non-GL video mode first");
+ return(-1);
+ }
+ return(DX5_AllocDDSurface(this, surface, NULL, SDL_HWSURFACE));
+}
+
+#ifdef DDRAW_DEBUG
+void PrintSurface(char *title, LPDIRECTDRAWSURFACE3 surface, Uint32 flags)
+{
+ DDSURFACEDESC ddsd;
+
+ /* Lock and load! */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ if ( IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
+ (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL) != DD_OK ) {
+ return;
+ }
+ IDirectDrawSurface3_Unlock(surface, NULL);
+
+ fprintf(stderr, "%s:\n", title);
+ fprintf(stderr, "\tSize: %dx%d in %s at %ld bpp (pitch = %ld)\n",
+ ddsd.dwWidth, ddsd.dwHeight,
+ (flags & SDL_HWSURFACE) ? "hardware" : "software",
+#if defined(NONAMELESSUNION)
+ ddsd.ddpfPixelFormat.u1.dwRGBBitCount, ddsd.u1.lPitch);
+#else
+ ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.lPitch);
+#endif
+ fprintf(stderr, "\tR = 0x%X, G = 0x%X, B = 0x%X\n",
+#if defined(NONAMELESSUNION)
+ ddsd.ddpfPixelFormat.u2.dwRBitMask,
+ ddsd.ddpfPixelFormat.u3.dwGBitMask,
+ ddsd.ddpfPixelFormat.u4.dwBBitMask);
+#else
+ ddsd.ddpfPixelFormat.dwRBitMask,
+ ddsd.ddpfPixelFormat.dwGBitMask,
+ ddsd.ddpfPixelFormat.dwBBitMask);
+#endif
+}
+#endif /* DDRAW_DEBUG */
+
+static int DX5_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ LPDIRECTDRAWSURFACE3 src_surface;
+ LPDIRECTDRAWSURFACE3 dst_surface;
+ DWORD flags;
+ RECT rect;
+ HRESULT result;
+
+ /* Set it up.. the desination must have a DDRAW surface */
+ src_surface = src->hwdata->dd_writebuf;
+ dst_surface = dst->hwdata->dd_writebuf;
+ rect.top = (LONG)srcrect->y;
+ rect.bottom = (LONG)srcrect->y+srcrect->h;
+ rect.left = (LONG)srcrect->x;
+ rect.right = (LONG)srcrect->x+srcrect->w;
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY )
+ flags = DDBLTFAST_SRCCOLORKEY;
+ else
+ flags = DDBLTFAST_NOCOLORKEY;
+ /* FIXME: We can remove this flag for _really_ fast blit queuing,
+ but it will affect the return values of locks and flips.
+ */
+ flags |= DDBLTFAST_WAIT;
+
+ /* Do the blit! */
+ result = IDirectDrawSurface3_BltFast(dst_surface,
+ dstrect->x, dstrect->y, src_surface, &rect, flags);
+ if ( result != DD_OK ) {
+ if ( result == DDERR_SURFACELOST ) {
+ result = IDirectDrawSurface3_Restore(src_surface);
+ result = IDirectDrawSurface3_Restore(dst_surface);
+ /* The surfaces need to be reloaded with artwork */
+ SDL_SetError("Blit surfaces were lost, reload them");
+ return(-2);
+ }
+ SetDDerror("IDirectDrawSurface3::BltFast", result);
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "Original dest rect: %dx%d at %d,%d\n", dstrect->w, dstrect->h, dstrect->x, dstrect->y);
+ fprintf(stderr, "HW accelerated %sblit to from 0x%p to 0x%p at (%d,%d)\n",
+ (src->flags & SDL_SRCCOLORKEY) ? "colorkey " : "", src, dst,
+ dstrect->x, dstrect->y);
+ PrintSurface("SRC", src_surface, src->flags);
+ PrintSurface("DST", dst_surface, dst->flags);
+ fprintf(stderr, "Source rectangle: (%d,%d) - (%d,%d)\n",
+ rect.left, rect.top, rect.right, rect.bottom);
+#endif
+ /* Unexpected error, fall back to software blit */
+ return(src->map->sw_blit(src, srcrect, dst, dstrect));
+ }
+ return(0);
+}
+
+static int DX5_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+ int accelerated;
+
+ /* We need to have a DDraw surface for HW blits */
+ if ( (src->flags & SDL_HWSURFACE) == SDL_SWSURFACE ) {
+ /* Allocate a DDraw surface for the blit */
+ if ( src->hwdata == NULL ) {
+ DX5_AllocDDSurface(this, src, NULL, SDL_SWSURFACE);
+ }
+ }
+ if ( src->hwdata == NULL ) {
+ return(0);
+ }
+
+ /* Set initial acceleration on */
+ src->flags |= SDL_HWACCEL;
+
+ /* Set the surface attributes */
+ if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
+ if ( DX5_SetHWColorKey(this, src, src->format->colorkey) < 0 ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+ if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+ if ( DX5_SetHWAlpha(this, src, src->format->alpha) < 0 ) {
+ src->flags &= ~SDL_HWACCEL;
+ }
+ }
+
+ /* Check to see if final surface blit is accelerated */
+ accelerated = !!(src->flags & SDL_HWACCEL);
+ if ( accelerated ) {
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "Setting accelerated blit on 0x%p\n", src);
+#endif
+ src->map->hw_blit = DX5_HWAccelBlit;
+ }
+ return(accelerated);
+}
+
+static int DX5_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
+{
+ LPDIRECTDRAWSURFACE3 dst_surface;
+ RECT area;
+ DDBLTFX bltfx;
+ HRESULT result;
+
+#ifdef DDRAW_DEBUG
+ fprintf(stderr, "HW accelerated fill at (%d,%d)\n", dstrect->x, dstrect->y);
+#endif
+ dst_surface = dst->hwdata->dd_writebuf;
+ area.top = (LONG)dstrect->y;
+ area.bottom = (LONG)dstrect->y+dstrect->h;
+ area.left = (LONG)dstrect->x;
+ area.right = (LONG)dstrect->x+dstrect->w;
+ bltfx.dwSize = sizeof(bltfx);
+#if defined(NONAMELESSUNION)
+ bltfx.u5.dwFillColor = color;
+#else
+ bltfx.dwFillColor = color;
+#endif
+ result = IDirectDrawSurface3_Blt(dst_surface,
+ &area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);
+ if ( result == DDERR_SURFACELOST ) {
+ IDirectDrawSurface3_Restore(dst_surface);
+ result = IDirectDrawSurface3_Blt(dst_surface,
+ &area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);
+ }
+ if ( result != DD_OK ) {
+ SetDDerror("IDirectDrawSurface3::Blt", result);
+ return(-1);
+ }
+ return(0);
+}
+
+static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+ DDCOLORKEY colorkey;
+ HRESULT result;
+
+ /* Set the surface colorkey */
+ colorkey.dwColorSpaceLowValue = key;
+ colorkey.dwColorSpaceHighValue = key;
+ result = IDirectDrawSurface3_SetColorKey(
+ surface->hwdata->dd_surface, DDCKEY_SRCBLT, &colorkey);
+ if ( result != DD_OK ) {
+ SetDDerror("IDirectDrawSurface3::SetColorKey", result);
+ return(-1);
+ }
+ return(0);
+}
+static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
+{
+ return(-1);
+}
+
+static int DX5_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ HRESULT result;
+ LPDIRECTDRAWSURFACE3 dd_surface;
+ DDSURFACEDESC ddsd;
+
+ /* Lock and load! */
+ dd_surface = surface->hwdata->dd_writebuf;
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
+ (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
+ if ( result == DDERR_SURFACELOST ) {
+ result = IDirectDrawSurface3_Restore(
+ surface->hwdata->dd_surface);
+ result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,
+ (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
+ }
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Lock", result);
+ return(-1);
+ }
+ /* Pitch might have changed -- recalculate pitch and offset */
+#if defined(NONAMELESSUNION)
+ if ( surface->pitch != ddsd.u1.lPitch ) {
+ surface->pitch = ddsd.u1.lPitch;
+#else
+ if ( surface->pitch != ddsd.lPitch ) {
+ surface->pitch = (Uint16)ddsd.lPitch;
+#endif
+ surface->offset =
+ ((ddsd.dwHeight-surface->h)/2)*surface->pitch +
+ ((ddsd.dwWidth-surface->w)/2)*
+ surface->format->BytesPerPixel;
+ }
+ surface->pixels = ddsd.lpSurface;
+ return(0);
+}
+
+static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ IDirectDrawSurface3_Unlock(surface->hwdata->dd_writebuf, NULL);
+ surface->pixels = NULL;
+}
+
+static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ HRESULT result;
+ LPDIRECTDRAWSURFACE3 dd_surface;
+
+ dd_surface = surface->hwdata->dd_surface;
+
+ /* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
+ /* Dmitry Yakimov (ftech@tula.net) */
+ while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
+
+ result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
+ if ( result == DDERR_SURFACELOST ) {
+ result = IDirectDrawSurface3_Restore(
+ surface->hwdata->dd_surface);
+ while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
+ result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
+ }
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Flip", result);
+ return(-1);
+ }
+ return(0);
+}
+
+static void DX5_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( surface->hwdata ) {
+ if ( surface->hwdata->dd_surface != SDL_primary ) {
+ IDirectDrawSurface3_Release(surface->hwdata->dd_surface);
+ }
+ SDL_free(surface->hwdata);
+ surface->hwdata = NULL;
+ }
+}
+
+void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ HRESULT result;
+ int i;
+ RECT src, dst;
+
+ for ( i=0; i<numrects; ++i ) {
+ src.top = (LONG)rects[i].y;
+ src.bottom = (LONG)rects[i].y+rects[i].h;
+ src.left = (LONG)rects[i].x;
+ src.right = (LONG)rects[i].x+rects[i].w;
+ dst.top = SDL_bounds.top+src.top;
+ dst.left = SDL_bounds.left+src.left;
+ dst.bottom = SDL_bounds.top+src.bottom;
+ dst.right = SDL_bounds.left+src.right;
+ result = IDirectDrawSurface3_Blt(SDL_primary, &dst,
+ this->screen->hwdata->dd_surface, &src,
+ DDBLT_WAIT, NULL);
+ /* Doh! Check for lost surface and restore it */
+ if ( result == DDERR_SURFACELOST ) {
+ IDirectDrawSurface3_Restore(SDL_primary);
+ IDirectDrawSurface3_Blt(SDL_primary, &dst,
+ this->screen->hwdata->dd_surface, &src,
+ DDBLT_WAIT, NULL);
+ }
+ }
+}
+
+void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+}
+
+/* Compress a full palette into the limited number of colors given to us
+ by windows.
+
+ The "best" way to do this is to sort the colors by diversity and place
+ the most diverse colors into the limited palette. Unfortunately this
+ results in widely varying colors being displayed in the interval during
+ which the windows palette has been set, and the mapping of the shadow
+ surface to the new palette. This is especially noticeable during fades.
+
+ To deal with this problem, we can copy a predetermined portion of the
+ full palette, and use that as the limited palette. This allows colors
+ to fade smoothly as the remapping is very similar on each palette change.
+ Unfortunately, this breaks applications which partition the palette into
+ distinct and widely varying areas, expecting all colors to be available.
+
+ I'm making them both available, chosen at compile time.
+ If you want the chunk-o-palette algorithm, define SIMPLE_COMPRESSION,
+ otherwise the sort-by-diversity algorithm will be used.
+*/
+#define SIMPLE_COMPRESSION
+#define CS_CS_DIST(A, B) ({ \
+ int r = (A.r - B.r); \
+ int g = (A.g - B.g); \
+ int b = (A.b - B.b); \
+ (r*r + g*g + b*b); \
+})
+static void DX5_CompressPalette(_THIS, SDL_Color *colors, int ncolors, int maxcolors)
+{
+#ifdef SIMPLE_COMPRESSION
+ int i, j;
+#else
+ static SDL_Color zero = { 0, 0, 0, 0 };
+ int i, j;
+ int max, dist;
+ int prev, next;
+ int *pool;
+ int *seen, *order;
+#endif
+
+ /* Does this happen? */
+ if ( maxcolors > ncolors ) {
+ maxcolors = ncolors;
+ }
+
+#ifdef SIMPLE_COMPRESSION
+ /* Just copy the first "maxcolors" colors */
+ for ( j=10, i=0; i<maxcolors; ++i, ++j ) {
+ SDL_colors[j].peRed = colors[i].r;
+ SDL_colors[j].peGreen = colors[i].g;
+ SDL_colors[j].peBlue = colors[i].b;
+ }
+#else
+ /* Allocate memory for the arrays we use */
+ pool = SDL_stack_alloc(int, 2*ncolors);
+ if ( pool == NULL ) {
+ /* No worries, just return */;
+ return;
+ }
+ seen = pool;
+ SDL_memset(seen, 0, ncolors*sizeof(int));
+ order = pool+ncolors;
+
+ /* Start with the brightest color */
+ max = 0;
+ for ( i=0; i<ncolors; ++i ) {
+ dist = CS_CS_DIST(zero, colors[i]);
+ if ( dist >= max ) {
+ max = dist;
+ next = i;
+ }
+ }
+ j = 0;
+ order[j++] = next;
+ seen[next] = 1;
+ prev = next;
+
+ /* Keep going through all the colors */
+ while ( j < maxcolors ) {
+ max = 0;
+ for ( i=0; i<ncolors; ++i ) {
+ if ( seen[i] ) {
+ continue;
+ }
+ dist = CS_CS_DIST(colors[i], colors[prev]);
+ if ( dist >= max ) {
+ max = dist;
+ next = i;
+ }
+ }
+ order[j++] = next;
+ seen[next] = 1;
+ prev = next;
+ }
+
+ /* Compress the colors to the palette */
+ for ( j=10, i=0; i<maxcolors; ++i, ++j ) {
+ SDL_colors[j].peRed = colors[order[i]].r;
+ SDL_colors[j].peGreen = colors[order[i]].g;
+ SDL_colors[j].peBlue = colors[order[i]].b;
+ }
+ SDL_stack_free(pool);
+#endif /* SIMPLE_COMPRESSION */
+}
+
+/* Set the system colormap in both fullscreen and windowed modes */
+int DX5_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int i;
+ int alloct_all;
+
+ /* Copy palette colors into display palette */
+ alloct_all = 0;
+ if ( SDL_palette != NULL ) {
+ if ( (this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
+ /* We can set all entries explicitly */
+ for ( i=0; i< ncolors; ++i ) {
+ int j = firstcolor + i;
+ SDL_colors[j].peRed = colors[i].r;
+ SDL_colors[j].peGreen = colors[i].g;
+ SDL_colors[j].peBlue = colors[i].b;
+ }
+ /* This sends an WM_PALETTECHANGED message to us */
+ colorchange_expected = 1;
+ IDirectDrawPalette_SetEntries(SDL_palette, 0,
+ firstcolor, ncolors, &SDL_colors[firstcolor]);
+ alloct_all = 1;
+ } else {
+ /* Grab the 236 most diverse colors in the palette */
+ DX5_CompressPalette(this, colors, ncolors, 236);
+ /* This sends an WM_PALETTECHANGED message to us */
+ colorchange_expected = 1;
+ IDirectDrawPalette_SetEntries(SDL_palette, 0,
+ 0, 256, SDL_colors);
+ }
+ }
+ return(alloct_all);
+}
+
+/* Gamma code is only available on DirectX 7 and newer */
+static int DX5_SetGammaRamp(_THIS, Uint16 *ramp)
+{
+#ifdef IDirectDrawGammaControl_SetGammaRamp
+ LPDIRECTDRAWGAMMACONTROL gamma;
+ DDGAMMARAMP gamma_ramp;
+ HRESULT result;
+#endif
+
+ /* In windowed or OpenGL mode, use windib gamma code */
+ if ( ! DDRAW_FULLSCREEN() ) {
+ return DIB_SetGammaRamp(this, ramp);
+ }
+
+#ifndef IDirectDrawGammaControl_SetGammaRamp
+ SDL_SetError("SDL compiled without DirectX gamma ramp support");
+ return -1;
+#else
+ /* Check for a video mode! */
+ if ( ! SDL_primary ) {
+ SDL_SetError("A video mode must be set for gamma correction");
+ return(-1);
+ }
+
+ /* Get the gamma control object */
+ result = IDirectDrawSurface3_QueryInterface(SDL_primary,
+ &IID_IDirectDrawGammaControl, (LPVOID *)&gamma);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::QueryInterface(GAMMA)", result);
+ return(-1);
+ }
+
+ /* Set up the gamma ramp */
+ SDL_memcpy(gamma_ramp.red, &ramp[0*256], 256*sizeof(*ramp));
+ SDL_memcpy(gamma_ramp.green, &ramp[1*256], 256*sizeof(*ramp));
+ SDL_memcpy(gamma_ramp.blue, &ramp[2*256], 256*sizeof(*ramp));
+ result = IDirectDrawGammaControl_SetGammaRamp(gamma, 0, &gamma_ramp);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawGammaControl::SetGammaRamp()", result);
+ }
+
+ /* Release the interface and return */
+ IDirectDrawGammaControl_Release(gamma);
+ return (result == DD_OK) ? 0 : -1;
+#endif /* !IDirectDrawGammaControl_SetGammaRamp */
+}
+
+static int DX5_GetGammaRamp(_THIS, Uint16 *ramp)
+{
+#ifdef IDirectDrawGammaControl_SetGammaRamp
+ LPDIRECTDRAWGAMMACONTROL gamma;
+ DDGAMMARAMP gamma_ramp;
+ HRESULT result;
+#endif
+
+ /* In windowed or OpenGL mode, use windib gamma code */
+ if ( ! DDRAW_FULLSCREEN() ) {
+ return DIB_GetGammaRamp(this, ramp);
+ }
+
+#ifndef IDirectDrawGammaControl_SetGammaRamp
+ SDL_SetError("SDL compiled without DirectX gamma ramp support");
+ return -1;
+#else
+ /* Check for a video mode! */
+ if ( ! SDL_primary ) {
+ SDL_SetError("A video mode must be set for gamma correction");
+ return(-1);
+ }
+
+ /* Get the gamma control object */
+ result = IDirectDrawSurface3_QueryInterface(SDL_primary,
+ &IID_IDirectDrawGammaControl, (LPVOID *)&gamma);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::QueryInterface(GAMMA)", result);
+ return(-1);
+ }
+
+ /* Set up the gamma ramp */
+ result = IDirectDrawGammaControl_GetGammaRamp(gamma, 0, &gamma_ramp);
+ if ( result == DD_OK ) {
+ SDL_memcpy(&ramp[0*256], gamma_ramp.red, 256*sizeof(*ramp));
+ SDL_memcpy(&ramp[1*256], gamma_ramp.green, 256*sizeof(*ramp));
+ SDL_memcpy(&ramp[2*256], gamma_ramp.blue, 256*sizeof(*ramp));
+ } else {
+ SetDDerror("DirectDrawGammaControl::GetGammaRamp()", result);
+ }
+
+ /* Release the interface and return */
+ IDirectDrawGammaControl_Release(gamma);
+ return (result == DD_OK) ? 0 : -1;
+#endif /* !IDirectDrawGammaControl_SetGammaRamp */
+}
+
+void DX5_VideoQuit(_THIS)
+{
+ int i, j;
+
+ /* If we're fullscreen GL, we need to reset the display */
+ if ( this->screen != NULL ) {
+#ifndef NO_CHANGEDISPLAYSETTINGS
+ if ( (this->screen->flags & (SDL_OPENGL|SDL_FULLSCREEN)) ==
+ (SDL_OPENGL|SDL_FULLSCREEN) ) {
+ ChangeDisplaySettings(NULL, 0);
+ ShowWindow(SDL_Window, SW_HIDE);
+ }
+#endif
+ if ( this->screen->flags & SDL_OPENGL ) {
+ WIN_GL_ShutDown(this);
+ }
+ }
+
+ /* Free any palettes we used */
+ if ( SDL_palette != NULL ) {
+ IDirectDrawPalette_Release(SDL_palette);
+ SDL_palette = NULL;
+ }
+
+ /* Allow the primary surface to be freed */
+ if ( SDL_primary != NULL ) {
+ SDL_primary = NULL;
+ }
+
+ /* Free video mode lists */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ for ( j=0; SDL_modelist[i][j]; ++j )
+ SDL_free(SDL_modelist[i][j]);
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ }
+
+ /* Free the window */
+ DIB_QuitGamma(this);
+ if ( SDL_Window ) {
+ DX5_DestroyWindow(this);
+ }
+
+ /* Free our window icon */
+ if ( screen_icn ) {
+ DestroyIcon(screen_icn);
+ screen_icn = NULL;
+ }
+}
+
+/* Exported for the windows message loop only */
+void DX5_Activate(_THIS, BOOL active, BOOL minimized)
+{
+}
+void DX5_RealizePalette(_THIS)
+{
+ if ( SDL_palette ) {
+ IDirectDrawSurface3_SetPalette(SDL_primary, SDL_palette);
+ }
+}
+static void DX5_Recolor8Bit(_THIS, SDL_Surface *surface, Uint8 *mapping)
+{
+ int row, col;
+ Uint8 *pixels;
+
+ if ( surface->w && surface->h ) {
+ if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ if ( this->LockHWSurface(this, surface) < 0 ) {
+ return;
+ }
+ }
+ for ( row=0; row<surface->h; ++row ) {
+ pixels = (Uint8 *)surface->pixels+row*surface->pitch;
+ for ( col=0; col<surface->w; ++col, ++pixels ) {
+ *pixels = mapping[*pixels];
+ }
+ }
+ if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
+ this->UnlockHWSurface(this, surface);
+ }
+ SDL_UpdateRect(surface, 0, 0, 0, 0);
+ }
+}
+void DX5_PaletteChanged(_THIS, HWND window)
+{
+ SDL_Palette *palette;
+ SDL_Color *saved = NULL;
+ HDC hdc;
+ int i;
+ PALETTEENTRY *entries;
+
+ /* This is true when the window is closing */
+ if ( (SDL_primary == NULL) || (SDL_VideoSurface == NULL) )
+ return;
+
+ /* We need to get the colors as they were set */
+ palette = this->physpal;
+ if(!palette)
+ palette = SDL_VideoSurface->format->palette;
+ if ( palette == NULL ) { /* Sometimes we don't have a palette */
+ return;
+ }
+ entries = SDL_stack_alloc(PALETTEENTRY, palette->ncolors);
+ hdc = GetDC(window);
+ GetSystemPaletteEntries(hdc, 0, palette->ncolors, entries);
+ ReleaseDC(window, hdc);
+ if ( ! colorchange_expected ) {
+ saved = SDL_stack_alloc(SDL_Color, palette->ncolors);
+ SDL_memcpy(saved, palette->colors,
+ palette->ncolors*sizeof(SDL_Color));
+ }
+ for ( i=0; i<palette->ncolors; ++i ) {
+ palette->colors[i].r = entries[i].peRed;
+ palette->colors[i].g = entries[i].peGreen;
+ palette->colors[i].b = entries[i].peBlue;
+ }
+ SDL_stack_free(entries);
+ if ( ! colorchange_expected ) {
+ Uint8 mapping[256];
+
+ SDL_memset(mapping, 0, sizeof(mapping));
+ for ( i=0; i<palette->ncolors; ++i ) {
+ mapping[i] = SDL_FindColor(palette,
+ saved[i].r, saved[i].g, saved[i].b);
+ }
+ DX5_Recolor8Bit(this, SDL_VideoSurface, mapping);
+ SDL_stack_free(saved);
+ }
+ colorchange_expected = 0;
+
+ /* Notify all mapped surfaces of the change */
+ SDL_FormatChanged(SDL_VideoSurface);
+}
+
+/* Exported for the windows message loop only */
+void DX5_WinPAINT(_THIS, HDC hdc)
+{
+ SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);
+}
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.h b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.h
new file mode 100644
index 0000000..3d754a0
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5video.h
@@ -0,0 +1,61 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_dx5video_h
+#define _SDL_dx5video_h
+
+#include "directx.h"
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ LPDIRECTDRAW2 ddraw2;
+ LPDIRECTDRAWSURFACE3 SDL_primary;
+ LPDIRECTDRAWCLIPPER SDL_clipper;
+ LPDIRECTDRAWPALETTE SDL_palette;
+ PALETTEENTRY SDL_colors[256];
+ int colorchange_expected;
+
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ int SDL_modeindex[NUM_MODELISTS];
+};
+/* Old variable names */
+#define ddraw2 (this->hidden->ddraw2)
+#define SDL_primary (this->hidden->SDL_primary)
+#define SDL_clipper (this->hidden->SDL_clipper)
+#define SDL_palette (this->hidden->SDL_palette)
+#define SDL_colors (this->hidden->SDL_colors)
+#define colorchange_expected (this->hidden->colorchange_expected)
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define SDL_modeindex (this->hidden->SDL_modeindex)
+
+/* DirectX function pointers for video and events */
+extern HRESULT (WINAPI *DDrawCreate)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
+extern HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
+
+/* DirectDraw error reporting function */
+extern void SetDDerror(const char *function, int code);
+
+#endif /* _SDL_dx5video_h */
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv.c b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv.c
new file mode 100644
index 0000000..cb89fdc
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv.c
@@ -0,0 +1,296 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the DirectDraw implementation of YUV video overlays */
+#include "directx.h"
+#include "SDL_video.h"
+#include "SDL_dx5yuv_c.h"
+#include "../SDL_yuvfuncs.h"
+
+//#define USE_DIRECTX_OVERLAY
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs dx5_yuvfuncs = {
+ DX5_LockYUVOverlay,
+ DX5_UnlockYUVOverlay,
+ DX5_DisplayYUVOverlay,
+ DX5_FreeYUVOverlay
+};
+
+struct private_yuvhwdata {
+ LPDIRECTDRAWSURFACE3 surface;
+
+ /* These are just so we don't have to allocate them separately */
+ Uint16 pitches[3];
+ Uint8 *planes[3];
+};
+
+
+static LPDIRECTDRAWSURFACE3 CreateYUVSurface(_THIS,
+ int width, int height, Uint32 format)
+{
+ HRESULT result;
+ LPDIRECTDRAWSURFACE dd_surface1;
+ LPDIRECTDRAWSURFACE3 dd_surface3;
+ DDSURFACEDESC ddsd;
+
+ /* Set up the surface description */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT);
+ ddsd.dwWidth = width;
+ ddsd.dwHeight= height;
+#ifdef USE_DIRECTX_OVERLAY
+ ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY);
+#else
+ ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);
+#endif
+ ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
+ ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ ddsd.ddpfPixelFormat.dwFourCC = format;
+
+ /* Create the DirectDraw video surface */
+ result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDraw2::CreateSurface", result);
+ return(NULL);
+ }
+ result = IDirectDrawSurface_QueryInterface(dd_surface1,
+ &IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);
+ IDirectDrawSurface_Release(dd_surface1);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface::QueryInterface", result);
+ return(NULL);
+ }
+
+ /* Make sure the surface format was set properly */
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
+ &ddsd, DDLOCK_NOSYSLOCK, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Lock", result);
+ IDirectDrawSurface_Release(dd_surface3);
+ return(NULL);
+ }
+ IDirectDrawSurface3_Unlock(dd_surface3, NULL);
+
+ if ( !(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
+ (ddsd.ddpfPixelFormat.dwFourCC != format) ) {
+ SDL_SetError("DDraw didn't use requested FourCC format");
+ IDirectDrawSurface_Release(dd_surface3);
+ return(NULL);
+ }
+
+ /* We're ready to go! */
+ return(dd_surface3);
+}
+
+#ifdef DEBUG_YUV
+static char *PrintFOURCC(Uint32 code)
+{
+ static char buf[5];
+
+ buf[3] = code >> 24;
+ buf[2] = (code >> 16) & 0xFF;
+ buf[1] = (code >> 8) & 0xFF;
+ buf[0] = (code & 0xFF);
+ return(buf);
+}
+#endif
+
+SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+ SDL_Overlay *overlay;
+ struct private_yuvhwdata *hwdata;
+
+#ifdef DEBUG_YUV
+ DWORD numcodes;
+ DWORD *codes;
+
+ printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format));
+ IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL);
+ if ( numcodes ) {
+ DWORD i;
+ codes = SDL_malloc(numcodes*sizeof(*codes));
+ if ( codes ) {
+ IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes);
+ for ( i=0; i<numcodes; ++i ) {
+ fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i]));
+ }
+ SDL_free(codes);
+ }
+ } else {
+ fprintf(stderr, "No FOURCC codes supported\n");
+ }
+#endif
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
+ if ( overlay == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(overlay, 0, (sizeof *overlay));
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &dx5_yuvfuncs;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
+ overlay->hwdata = hwdata;
+ if ( hwdata == NULL ) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ hwdata->surface = CreateYUVSurface(this, width, height, format);
+ if ( hwdata->surface == NULL ) {
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ overlay->hw_overlay = 1;
+
+ /* Set up the plane pointers */
+ overlay->pitches = hwdata->pitches;
+ overlay->pixels = hwdata->planes;
+ switch (format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ overlay->planes = 3;
+ break;
+ default:
+ overlay->planes = 1;
+ break;
+ }
+
+ /* We're all done.. */
+ return(overlay);
+}
+
+int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ HRESULT result;
+ LPDIRECTDRAWSURFACE3 surface;
+ DDSURFACEDESC ddsd;
+
+ surface = overlay->hwdata->surface;
+ SDL_memset(&ddsd, 0, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ result = IDirectDrawSurface3_Lock(surface, NULL,
+ &ddsd, DDLOCK_NOSYSLOCK, NULL);
+ if ( result == DDERR_SURFACELOST ) {
+ result = IDirectDrawSurface3_Restore(surface);
+ result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
+ (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);
+ }
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Lock", result);
+ return(-1);
+ }
+
+ /* Find the pitch and offset values for the overlay */
+#if defined(NONAMELESSUNION)
+ overlay->pitches[0] = (Uint16)ddsd.u1.lPitch;
+#else
+ overlay->pitches[0] = (Uint16)ddsd.lPitch;
+#endif
+ overlay->pixels[0] = (Uint8 *)ddsd.lpSurface;
+ switch (overlay->format) {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ /* Add the two extra planes */
+ overlay->pitches[1] = overlay->pitches[0] / 2;
+ overlay->pitches[2] = overlay->pitches[0] / 2;
+ overlay->pixels[1] = overlay->pixels[0] +
+ overlay->pitches[0] * overlay->h;
+ overlay->pixels[2] = overlay->pixels[1] +
+ overlay->pitches[1] * overlay->h / 2;
+ break;
+ default:
+ /* Only one plane, no worries */
+ break;
+ }
+ return(0);
+}
+
+void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ LPDIRECTDRAWSURFACE3 surface;
+
+ surface = overlay->hwdata->surface;
+ IDirectDrawSurface3_Unlock(surface, NULL);
+}
+
+int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
+{
+ HRESULT result;
+ LPDIRECTDRAWSURFACE3 surface;
+ RECT srcrect, dstrect;
+
+ surface = overlay->hwdata->surface;
+ srcrect.top = src->y;
+ srcrect.bottom = srcrect.top+src->h;
+ srcrect.left = src->x;
+ srcrect.right = srcrect.left+src->w;
+ dstrect.top = SDL_bounds.top+dst->y;
+ dstrect.left = SDL_bounds.left+dst->x;
+ dstrect.bottom = dstrect.top+dst->h;
+ dstrect.right = dstrect.left+dst->w;
+#ifdef USE_DIRECTX_OVERLAY
+ result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect,
+ SDL_primary, &dstrect, DDOVER_SHOW, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::UpdateOverlay", result);
+ return(-1);
+ }
+#else
+ result = IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect,
+ DDBLT_WAIT, NULL);
+ if ( result != DD_OK ) {
+ SetDDerror("DirectDrawSurface3::Blt", result);
+ return(-1);
+ }
+#endif
+ return(0);
+}
+
+void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ struct private_yuvhwdata *hwdata;
+
+ hwdata = overlay->hwdata;
+ if ( hwdata ) {
+ if ( hwdata->surface ) {
+ IDirectDrawSurface_Release(hwdata->surface);
+ }
+ SDL_free(hwdata);
+ overlay->hwdata = NULL;
+ }
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv_c.h b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv_c.h
new file mode 100644
index 0000000..dfceaf9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/SDL_dx5yuv_c.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the DirectDraw implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "../wincommon/SDL_lowvideo.h"
+#include "SDL_dx5video.h"
+
+extern SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int DX5_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+
+extern void DX5_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
diff --git a/distrib/sdl-1.2.15/src/video/windx5/directx.h b/distrib/sdl-1.2.15/src/video/windx5/directx.h
new file mode 100644
index 0000000..c7f5365
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/windx5/directx.h
@@ -0,0 +1,97 @@
+
+#ifndef _directx_h
+#define _directx_h
+
+/* Include all of the DirectX 5.0 headers and adds any necessary tweaks */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <mmsystem.h>
+#ifndef WIN32
+#define WIN32
+#endif
+#undef WINNT
+
+/* Far pointers don't exist in 32-bit code */
+#ifndef FAR
+#define FAR
+#endif
+
+/* Error codes not yet included in Win32 API header files */
+#ifndef MAKE_HRESULT
+#define MAKE_HRESULT(sev,fac,code) \
+ ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
+#endif
+
+#ifndef S_OK
+#define S_OK (HRESULT)0x00000000L
+#endif
+
+#ifndef SUCCEEDED
+#define SUCCEEDED(x) ((HRESULT)(x) >= 0)
+#endif
+#ifndef FAILED
+#define FAILED(x) ((HRESULT)(x)<0)
+#endif
+
+#ifndef E_FAIL
+#define E_FAIL (HRESULT)0x80000008L
+#endif
+#ifndef E_NOINTERFACE
+#define E_NOINTERFACE (HRESULT)0x80004002L
+#endif
+#ifndef E_OUTOFMEMORY
+#define E_OUTOFMEMORY (HRESULT)0x8007000EL
+#endif
+#ifndef E_INVALIDARG
+#define E_INVALIDARG (HRESULT)0x80070057L
+#endif
+#ifndef E_NOTIMPL
+#define E_NOTIMPL (HRESULT)0x80004001L
+#endif
+#ifndef REGDB_E_CLASSNOTREG
+#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
+#endif
+
+/* Severity codes */
+#ifndef SEVERITY_ERROR
+#define SEVERITY_ERROR 1
+#endif
+
+/* Error facility codes */
+#ifndef FACILITY_WIN32
+#define FACILITY_WIN32 7
+#endif
+
+#ifndef FIELD_OFFSET
+#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
+#endif
+
+/* DirectX headers (if it isn't included, I haven't tested it yet)
+ */
+/* We need these defines to mark what version of DirectX API we use */
+#define DIRECTDRAW_VERSION 0x0700
+#define DIRECTSOUND_VERSION 0x0500
+#define DIRECTINPUT_VERSION 0x0700
+
+#include <ddraw.h>
+#include <dsound.h>
+#include <dinput.h>
+
+#if DIRECTINPUT_VERSION >= 0x0700 && !defined(DIMOFS_BUTTON4)
+typedef struct _DIMOUSESTATE2 {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[8];
+} DIMOUSESTATE2, *LPDIMOUSESTATE2;
+
+#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
+#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
+#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
+#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
+
+extern const DIDATAFORMAT c_dfDIMouse2;
+#endif
+
+#endif /* _directx_h */
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents.c b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents.c
new file mode 100644
index 0000000..635b972
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents.c
@@ -0,0 +1,233 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <sys/types.h>
+#include <dev/wscons/wsdisplay_usl_io.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+#include <string.h>
+
+#include "SDL.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_wsconsvideo.h"
+#include "SDL_wsconsevents_c.h"
+
+static int posted = 0;
+
+int WSCONS_InitKeyboard(_THIS)
+{
+ struct termios tty;
+
+ if (ioctl(private->fd, WSKBDIO_GTYPE, &private->kbdType) == -1) {
+ WSCONS_ReportError("cannot get keyboard type: %s", strerror(errno));
+ return -1;
+ }
+
+ if (tcgetattr(private->fd, &private->saved_tty) == -1) {
+ WSCONS_ReportError("cannot get terminal attributes: %s", strerror(errno));
+ return -1;
+ }
+ private->did_save_tty = 1;
+ tty = private->saved_tty;
+ tty.c_iflag = IGNPAR | IGNBRK;
+ tty.c_oflag = 0;
+ tty.c_cflag = CREAD | CS8;
+ tty.c_lflag = 0;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+ cfsetispeed(&tty, 9600);
+ cfsetospeed(&tty, 9600);
+ if (tcsetattr(private->fd, TCSANOW, &tty) < 0) {
+ WSCONS_ReportError("cannot set terminal attributes: %s", strerror(errno));
+ return -1;
+ }
+ if (ioctl(private->fd, KDSKBMODE, K_RAW) == -1) {
+ WSCONS_ReportError("cannot set raw keyboard mode: %s", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+void WSCONS_ReleaseKeyboard(_THIS)
+{
+ if (private->fd != -1) {
+ if (ioctl(private->fd, KDSKBMODE, K_XLATE) == -1) {
+ WSCONS_ReportError("cannot restore keyboard to translated mode: %s",
+ strerror(errno));
+ }
+ if (private->did_save_tty) {
+ if (tcsetattr(private->fd, TCSANOW, &private->saved_tty) < 0) {
+ WSCONS_ReportError("cannot restore keynoard attributes: %s",
+ strerror(errno));
+ }
+ }
+ }
+}
+
+static void updateMouse()
+{
+}
+
+static SDLKey keymap[128];
+
+static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
+{
+ keysym->scancode = scancode;
+ keysym->sym = SDLK_UNKNOWN;
+ keysym->mod = KMOD_NONE;
+
+ if (scancode < SDL_arraysize(keymap))
+ keysym->sym = keymap[scancode];
+
+ if (keysym->sym == SDLK_UNKNOWN)
+ printf("Unknown mapping for scancode %d\n", scancode);
+
+ return keysym;
+}
+
+static void updateKeyboard(_THIS)
+{
+ unsigned char buf[100];
+ SDL_keysym keysym;
+ int n, i;
+
+ if ((n = read(private->fd, buf, sizeof(buf))) > 0) {
+ for (i = 0; i < n; i++) {
+ unsigned char c = buf[i] & 0x7f;
+ if (c == 224) // special key prefix -- what should we do with it?
+ continue;
+ posted += SDL_PrivateKeyboard((buf[i] & 0x80) ? SDL_RELEASED : SDL_PRESSED,
+ TranslateKey(c, &keysym));
+ }
+ }
+}
+
+void WSCONS_PumpEvents(_THIS)
+{
+ do {
+ posted = 0;
+ updateMouse();
+ updateKeyboard(this);
+ } while (posted);
+}
+
+void WSCONS_InitOSKeymap(_THIS)
+{
+ int i;
+
+ /* Make sure unknown keys are mapped correctly */
+ for (i=0; i < SDL_arraysize(keymap); i++) {
+ keymap[i] = SDLK_UNKNOWN;
+ }
+
+ switch (private->kbdType) {
+#ifdef WSKBD_TYPE_ZAURUS
+ case WSKBD_TYPE_ZAURUS:
+ /* top row */
+ keymap[2] = SDLK_1;
+ keymap[3] = SDLK_2;
+ keymap[4] = SDLK_3;
+ keymap[5] = SDLK_4;
+ keymap[6] = SDLK_5;
+ keymap[7] = SDLK_6;
+ keymap[8] = SDLK_7;
+ keymap[9] = SDLK_8;
+ keymap[10] = SDLK_9;
+ keymap[11] = SDLK_0;
+ keymap[14] = SDLK_BACKSPACE;
+
+ /* second row */
+ keymap[16] = SDLK_q;
+ keymap[17] = SDLK_w;
+ keymap[18] = SDLK_e;
+ keymap[19] = SDLK_r;
+ keymap[20] = SDLK_t;
+ keymap[21] = SDLK_y;
+ keymap[22] = SDLK_u;
+ keymap[23] = SDLK_i;
+ keymap[24] = SDLK_o;
+ keymap[25] = SDLK_p;
+
+ /* third row */
+ keymap[15] = SDLK_TAB;
+ keymap[30] = SDLK_a;
+ keymap[31] = SDLK_s;
+ keymap[32] = SDLK_d;
+ keymap[33] = SDLK_f;
+ keymap[34] = SDLK_g;
+ keymap[35] = SDLK_h;
+ keymap[36] = SDLK_j;
+ keymap[37] = SDLK_k;
+ keymap[38] = SDLK_l;
+
+ /* fourth row */
+ keymap[42] = SDLK_LSHIFT;
+ keymap[44] = SDLK_z;
+ keymap[45] = SDLK_x;
+ keymap[46] = SDLK_c;
+ keymap[47] = SDLK_v;
+ keymap[48] = SDLK_b;
+ keymap[49] = SDLK_n;
+ keymap[50] = SDLK_m;
+ keymap[54] = SDLK_RSHIFT;
+ keymap[28] = SDLK_RETURN;
+
+ /* fifth row */
+ keymap[56] = SDLK_LALT;
+ keymap[29] = SDLK_LCTRL;
+ /* keymap[56] = ; */
+ keymap[0] = SDLK_LSUPER;
+ keymap[12] = SDLK_MINUS;
+ keymap[57] = SDLK_SPACE;
+ keymap[51] = SDLK_COMMA;
+ keymap[52] = SDLK_PERIOD;
+
+ /* misc */
+ keymap[59] = SDLK_F1;
+ keymap[60] = SDLK_F2;
+ keymap[61] = SDLK_F3;
+ keymap[62] = SDLK_F4;
+ keymap[63] = SDLK_F5;
+ keymap[1] = SDLK_ESCAPE;
+ /* keymap[28] = SDLK_KP_ENTER; */
+ keymap[72] = SDLK_UP;
+ keymap[75] = SDLK_LEFT;
+ keymap[77] = SDLK_RIGHT;
+ keymap[80] = SDLK_DOWN;
+ break;
+#endif /* WSKBD_TYPE_ZAURUS */
+
+ default:
+ WSCONS_ReportError("Unable to map keys for keyboard type %u",
+ private->kbdType);
+ break;
+ }
+}
+
+/* end of SDL_wsconsevents.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents_c.h b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents_c.h
new file mode 100644
index 0000000..f68ee6e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsevents_c.h
@@ -0,0 +1,36 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_wsconsvideo.h"
+
+int WSCONS_InitKeyboard(_THIS);
+void WSCONS_ReleaseKeyboard(_THIS);
+
+/* Variables and functions exported by SDL_sysevents.c to other parts
+ of the native video subsystem (SDL_sysvideo.c)
+*/
+extern void WSCONS_InitOSKeymap(_THIS);
+extern void WSCONS_PumpEvents(_THIS);
+
+/* end of SDL_wsconsevents_c.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse.c b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse.c
new file mode 100644
index 0000000..b69e0c5
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse.c
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_wsconsmouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ int unused;
+};
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse_c.h b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse_c.h
new file mode 100644
index 0000000..875437b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsmouse_c.h
@@ -0,0 +1,26 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_wsconsvideo.h"
+
+/* Functions to be exported */
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.c b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.c
new file mode 100644
index 0000000..0e850d1
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.c
@@ -0,0 +1,609 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <dev/wscons/wsdisplay_usl_io.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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_wsconsvideo.h"
+#include "SDL_wsconsevents_c.h"
+#include "SDL_wsconsmouse_c.h"
+
+#define WSCONSVID_DRIVER_NAME "wscons"
+enum {
+ WSCONS_ROTATE_NONE = 0,
+ WSCONS_ROTATE_CCW = 90,
+ WSCONS_ROTATE_UD = 180,
+ WSCONS_ROTATE_CW = 270
+};
+
+#define min(a,b) ((a)<(b)?(a):(b))
+
+/* Initialization/Query functions */
+static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void WSCONS_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface);
+static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface);
+
+/* etc. */
+static WSCONS_bitBlit WSCONS_blit16;
+static WSCONS_bitBlit WSCONS_blit16blocked;
+static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+void WSCONS_ReportError(char *fmt, ...)
+{
+ char message[200];
+ va_list vaArgs;
+
+ message[199] = '\0';
+
+ va_start(vaArgs, fmt);
+ vsnprintf(message, 199, fmt, vaArgs);
+ va_end(vaArgs);
+
+ SDL_SetError(message);
+ fprintf(stderr, "WSCONS error: %s\n", message);
+}
+
+/* WSCONS driver bootstrap functions */
+
+static int WSCONS_Available(void)
+{
+ return 1;
+}
+
+static void WSCONS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *WSCONS_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden =
+ (struct SDL_PrivateVideoData *)SDL_malloc((sizeof *device->hidden));
+ if (device->hidden == NULL) {
+ SDL_OutOfMemory();
+ SDL_free(device);
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ device->hidden->fd = -1;
+
+ /* Set the function pointers */
+ device->VideoInit = WSCONS_VideoInit;
+ device->ListModes = WSCONS_ListModes;
+ device->SetVideoMode = WSCONS_SetVideoMode;
+ device->SetColors = WSCONS_SetColors;
+ device->UpdateRects = WSCONS_UpdateRects;
+ device->VideoQuit = WSCONS_VideoQuit;
+ device->AllocHWSurface = WSCONS_AllocHWSurface;
+ device->LockHWSurface = WSCONS_LockHWSurface;
+ device->UnlockHWSurface = WSCONS_UnlockHWSurface;
+ device->FreeHWSurface = WSCONS_FreeHWSurface;
+ device->InitOSKeymap = WSCONS_InitOSKeymap;
+ device->PumpEvents = WSCONS_PumpEvents;
+ device->free = WSCONS_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap WSCONS_bootstrap = {
+ WSCONSVID_DRIVER_NAME,
+ "SDL wscons video driver",
+ WSCONS_Available,
+ WSCONS_CreateDevice
+};
+
+#define WSCONSDEV_FORMAT "/dev/ttyC%01x"
+
+int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ char devnamebuf[30];
+ char *devname;
+ char *rotation;
+ int wstype;
+ int wsmode = WSDISPLAYIO_MODE_DUMBFB;
+ size_t len, mapsize;
+ int pagemask;
+ int width, height;
+
+ devname = SDL_getenv("SDL_WSCONSDEV");
+ if (devname == NULL) {
+ int activeVT;
+ if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) {
+ WSCONS_ReportError("Unable to determine active terminal: %s",
+ strerror(errno));
+ return -1;
+ }
+ SDL_snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1);
+ devname = devnamebuf;
+ }
+
+ private->fd = open(devname, O_RDWR | O_NONBLOCK, 0);
+ if (private->fd == -1) {
+ WSCONS_ReportError("open %s: %s", devname, strerror(errno));
+ return -1;
+ }
+ if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) {
+ WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno));
+ return -1;
+ }
+ if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
+ WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno));
+ return -1;
+ }
+ if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) {
+ WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno));
+ return -1;
+ }
+ if (private->info.depth > 8) {
+ if (wstype == WSDISPLAY_TYPE_SUN24 ||
+ wstype == WSDISPLAY_TYPE_SUNCG12 ||
+ wstype == WSDISPLAY_TYPE_SUNCG14 ||
+ wstype == WSDISPLAY_TYPE_SUNTCX ||
+ wstype == WSDISPLAY_TYPE_SUNFFB) {
+ private->redMask = 0x0000ff;
+ private->greenMask = 0x00ff00;
+ private->blueMask = 0xff0000;
+#ifdef WSDISPLAY_TYPE_PXALCD
+ } else if (wstype == WSDISPLAY_TYPE_PXALCD) {
+ private->redMask = 0x1f << 11;
+ private->greenMask = 0x3f << 5;
+ private->blueMask = 0x1f;
+#endif
+ } else {
+ WSCONS_ReportError("Unknown video hardware");
+ return -1;
+ }
+ } else {
+ WSCONS_ReportError("Displays with 8 bpp or less are not supported");
+ return -1;
+ }
+
+ private->rotate = WSCONS_ROTATE_NONE;
+ rotation = SDL_getenv("SDL_VIDEO_WSCONS_ROTATION");
+ if (rotation != NULL) {
+ if (SDL_strlen(rotation) == 0) {
+ private->shadowFB = 0;
+ private->rotate = WSCONS_ROTATE_NONE;
+ printf("Not rotating, no shadow\n");
+ } else if (!SDL_strcmp(rotation, "NONE")) {
+ private->shadowFB = 1;
+ private->rotate = WSCONS_ROTATE_NONE;
+ printf("Not rotating, but still using shadow\n");
+ } else if (!SDL_strcmp(rotation, "CW")) {
+ private->shadowFB = 1;
+ private->rotate = WSCONS_ROTATE_CW;
+ printf("Rotating screen clockwise\n");
+ } else if (!SDL_strcmp(rotation, "CCW")) {
+ private->shadowFB = 1;
+ private->rotate = WSCONS_ROTATE_CCW;
+ printf("Rotating screen counter clockwise\n");
+ } else if (!SDL_strcmp(rotation, "UD")) {
+ private->shadowFB = 1;
+ private->rotate = WSCONS_ROTATE_UD;
+ printf("Rotating screen upside down\n");
+ } else {
+ WSCONS_ReportError("\"%s\" is not a valid value for "
+ "SDL_VIDEO_WSCONS_ROTATION", rotation);
+ return -1;
+ }
+ }
+
+ switch (private->info.depth) {
+ case 1:
+ case 4:
+ case 8:
+ len = private->physlinebytes * private->info.height;
+ break;
+ case 16:
+ if (private->physlinebytes == private->info.width) {
+ len = private->info.width * private->info.height * sizeof(short);
+ } else {
+ len = private->physlinebytes * private->info.height;
+ }
+ if (private->rotate == WSCONS_ROTATE_NONE ||
+ private->rotate == WSCONS_ROTATE_UD) {
+ private->blitFunc = WSCONS_blit16;
+ } else {
+ private->blitFunc = WSCONS_blit16blocked;
+ }
+ break;
+ case 32:
+ if (private->physlinebytes == private->info.width) {
+ len = private->info.width * private->info.height * sizeof(int);
+ } else {
+ len = private->physlinebytes * private->info.height;
+ }
+ break;
+ default:
+ WSCONS_ReportError("unsupported depth %d", private->info.depth);
+ return -1;
+ }
+
+ if (private->shadowFB && private->blitFunc == NULL) {
+ WSCONS_ReportError("Using software buffer, but no blitter function is "
+ "available for this %d bpp.", private->info.depth);
+ return -1;
+ }
+
+ if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
+ WSCONS_ReportError("ioctl SMODE");
+ return -1;
+ }
+
+ pagemask = getpagesize() - 1;
+ mapsize = ((int)len + pagemask) & ~pagemask;
+ private->physmem = (Uint8 *)mmap(NULL, mapsize,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ private->fd, (off_t)0);
+ if (private->physmem == (Uint8 *)MAP_FAILED) {
+ private->physmem = NULL;
+ WSCONS_ReportError("mmap: %s", strerror(errno));
+ return -1;
+ }
+ private->fbmem_len = len;
+
+ if (private->rotate == WSCONS_ROTATE_CW ||
+ private->rotate == WSCONS_ROTATE_CCW) {
+ width = private->info.height;
+ height = private->info.width;
+ } else {
+ width = private->info.width;
+ height = private->info.height;
+ }
+
+ this->info.current_w = width;
+ this->info.current_h = height;
+
+ if (private->shadowFB) {
+ private->shadowmem = (Uint8 *)SDL_malloc(len);
+ if (private->shadowmem == NULL) {
+ WSCONS_ReportError("No memory for shadow");
+ return -1;
+ }
+ private->fbstart = private->shadowmem;
+ private->fblinebytes = width * ((private->info.depth + 7) / 8);
+ } else {
+ private->fbstart = private->physmem;
+ private->fblinebytes = private->physlinebytes;
+ }
+
+ private->SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ private->SDL_modelist[0]->w = width;
+ private->SDL_modelist[0]->h = height;
+
+ vformat->BitsPerPixel = private->info.depth;
+ vformat->BytesPerPixel = private->info.depth / 8;
+
+ if (WSCONS_InitKeyboard(this) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if (format->BitsPerPixel == private->info.depth) {
+ return private->SDL_modelist;
+ } else {
+ return NULL;
+ }
+}
+
+SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ if (width != private->SDL_modelist[0]->w ||
+ height != private->SDL_modelist[0]->h) {
+ WSCONS_ReportError("Requested video mode %dx%d not supported.",
+ width, height);
+ return NULL;
+ }
+ if (bpp != private->info.depth) {
+ WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp);
+ return NULL;
+ }
+
+ if (!SDL_ReallocFormat(current,
+ bpp,
+ private->redMask,
+ private->greenMask,
+ private->blueMask,
+ 0)) {
+ WSCONS_ReportError("Couldn't allocate new pixel format");
+ return NULL;
+ }
+
+ current->flags &= SDL_FULLSCREEN;
+ if (private->shadowFB) {
+ current->flags |= SDL_SWSURFACE;
+ } else {
+ current->flags |= SDL_HWSURFACE;
+ }
+ current->w = width;
+ current->h = height;
+ current->pitch = private->fblinebytes;
+ current->pixels = private->fbstart;
+
+ SDL_memset(private->fbstart, 0, private->fbmem_len);
+
+ return current;
+}
+
+static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return -1;
+}
+static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+}
+
+static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return 0;
+}
+
+static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+}
+
+static void WSCONS_blit16(Uint8 *byte_src_pos,
+ int srcRightDelta,
+ int srcDownDelta,
+ Uint8 *byte_dst_pos,
+ int dst_linebytes,
+ int width,
+ int height)
+{
+ int w;
+ Uint16 *src_pos = (Uint16 *)byte_src_pos;
+ Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
+
+ while (height) {
+ Uint16 *src = src_pos;
+ Uint16 *dst = dst_pos;
+ for (w = width; w != 0; w--) {
+ *dst = *src;
+ src += srcRightDelta;
+ dst++;
+ }
+ dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes);
+ src_pos += srcDownDelta;
+ height--;
+ }
+}
+
+#define BLOCKSIZE_W 32
+#define BLOCKSIZE_H 32
+
+static void WSCONS_blit16blocked(Uint8 *byte_src_pos,
+ int srcRightDelta,
+ int srcDownDelta,
+ Uint8 *byte_dst_pos,
+ int dst_linebytes,
+ int width,
+ int height)
+{
+ int w;
+ Uint16 *src_pos = (Uint16 *)byte_src_pos;
+ Uint16 *dst_pos = (Uint16 *)byte_dst_pos;
+
+ while (height > 0) {
+ Uint16 *src = src_pos;
+ Uint16 *dst = dst_pos;
+ for (w = width; w > 0; w -= BLOCKSIZE_W) {
+ WSCONS_blit16((Uint8 *)src,
+ srcRightDelta,
+ srcDownDelta,
+ (Uint8 *)dst,
+ dst_linebytes,
+ min(w, BLOCKSIZE_W),
+ min(height, BLOCKSIZE_H));
+ src += srcRightDelta * BLOCKSIZE_W;
+ dst += BLOCKSIZE_W;
+ }
+ dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H);
+ src_pos += srcDownDelta * BLOCKSIZE_H;
+ height -= BLOCKSIZE_H;
+ }
+}
+
+static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ int width = private->SDL_modelist[0]->w;
+ int height = private->SDL_modelist[0]->h;
+ int bytesPerPixel = (private->info.depth + 7) / 8;
+ int i;
+
+ if (!private->shadowFB) {
+ return;
+ }
+
+ if (private->info.depth != 16) {
+ WSCONS_ReportError("Shadow copy only implemented for 16 bpp");
+ return;
+ }
+
+ for (i = 0; i < numrects; i++) {
+ int x1, y1, x2, y2;
+ int scr_x1, scr_y1, scr_x2, scr_y2;
+ int sha_x1, sha_y1;
+ int shadowRightDelta; /* Address change when moving right in dest */
+ int shadowDownDelta; /* Address change when moving down in dest */
+ Uint8 *src_start;
+ Uint8 *dst_start;
+
+ x1 = rects[i].x;
+ y1 = rects[i].y;
+ x2 = x1 + rects[i].w;
+ y2 = y1 + rects[i].h;
+
+ if (x1 < 0) {
+ x1 = 0;
+ } else if (x1 > width) {
+ x1 = width;
+ }
+ if (x2 < 0) {
+ x2 = 0;
+ } else if (x2 > width) {
+ x2 = width;
+ }
+ if (y1 < 0) {
+ y1 = 0;
+ } else if (y1 > height) {
+ y1 = height;
+ }
+ if (y2 < 0) {
+ y2 = 0;
+ } else if (y2 > height) {
+ y2 = height;
+ }
+ if (x2 <= x1 || y2 <= y1) {
+ continue;
+ }
+
+ switch (private->rotate) {
+ case WSCONS_ROTATE_NONE:
+ sha_x1 = scr_x1 = x1;
+ sha_y1 = scr_y1 = y1;
+ scr_x2 = x2;
+ scr_y2 = y2;
+ shadowRightDelta = 1;
+ shadowDownDelta = width;
+ break;
+ case WSCONS_ROTATE_CCW:
+ scr_x1 = y1;
+ scr_y1 = width - x2;
+ scr_x2 = y2;
+ scr_y2 = width - x1;
+ sha_x1 = x2 - 1;
+ sha_y1 = y1;
+ shadowRightDelta = width;
+ shadowDownDelta = -1;
+ break;
+ case WSCONS_ROTATE_UD:
+ scr_x1 = width - x2;
+ scr_y1 = height - y2;
+ scr_x2 = width - x1;
+ scr_y2 = height - y1;
+ sha_x1 = x2 - 1;
+ sha_y1 = y2 - 1;
+ shadowRightDelta = -1;
+ shadowDownDelta = -width;
+ break;
+ case WSCONS_ROTATE_CW:
+ scr_x1 = height - y2;
+ scr_y1 = x1;
+ scr_x2 = height - y1;
+ scr_y2 = x2;
+ sha_x1 = x1;
+ sha_y1 = y2 - 1;
+ shadowRightDelta = -width;
+ shadowDownDelta = 1;
+ break;
+ default:
+ WSCONS_ReportError("Unknown rotation");
+ return;
+ }
+
+ src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel;
+ dst_start = private->physmem + scr_y1 * private->physlinebytes +
+ scr_x1 * bytesPerPixel;
+
+ private->blitFunc(src_start,
+ shadowRightDelta,
+ shadowDownDelta,
+ dst_start,
+ private->physlinebytes,
+ scr_x2 - scr_x1,
+ scr_y2 - scr_y1);
+ }
+}
+
+int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ return 0;
+}
+
+/*
+ * Note: If we are terminated, this could be called in the middle of
+ * another SDL video routine -- notably UpdateRects.
+ */
+void WSCONS_VideoQuit(_THIS)
+{
+ int mode = WSDISPLAYIO_MODE_EMUL;
+
+ if (private->shadowmem != NULL) {
+ SDL_free(private->shadowmem);
+ private->shadowmem = NULL;
+ }
+ private->fbstart = NULL;
+ if (this->screen != NULL) {
+ this->screen->pixels = NULL;
+ }
+
+ if (private->SDL_modelist[0] != NULL) {
+ SDL_free(private->SDL_modelist[0]);
+ private->SDL_modelist[0] = NULL;
+ }
+
+ if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) {
+ WSCONS_ReportError("ioctl SMODE");
+ }
+
+ WSCONS_ReleaseKeyboard(this);
+
+ if (private->fd != -1) {
+ close(private->fd);
+ private->fd = -1;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.h b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.h
new file mode 100644
index 0000000..9d75c17
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/wscons/SDL_wsconsvideo.h
@@ -0,0 +1,76 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_wsconsvideo_h
+#define _SDL_wsconsvideo_h
+
+#include <sys/time.h>
+#include <termios.h>
+#include <dev/wscons/wsconsio.h>
+
+#include "SDL_mouse.h"
+#include "SDL_mutex.h"
+#include "../SDL_sysvideo.h"
+
+void WSCONS_ReportError(char *fmt, ...);
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+#define private (this->hidden)
+
+/* Private display data */
+
+typedef void WSCONS_bitBlit(Uint8 *src_pos,
+ int srcRightDelta, // pixels, not bytes
+ int srcDownDelta, // pixels, not bytes
+ Uint8 *dst_pos,
+ int dst_linebytes,
+ int width,
+ int height);
+
+struct SDL_PrivateVideoData {
+ int fd; /* file descriptor of open device */
+ struct wsdisplay_fbinfo info; /* frame buffer characteristics */
+ int physlinebytes; /* number of bytes per row */
+ int redMask, greenMask, blueMask;
+
+ Uint8 *fbstart; /* These refer to the surface used, */
+ int fblinebytes; /* physical frame buffer or shadow. */
+
+ size_t fbmem_len;
+ Uint8 *physmem;
+ Uint8 *shadowmem;
+ int rotate;
+ int shadowFB; /* Tells whether a shadow is being used. */
+
+ WSCONS_bitBlit *blitFunc;
+
+ SDL_Rect *SDL_modelist[2];
+
+ unsigned int kbdType;
+ int did_save_tty;
+ struct termios saved_tty;
+};
+
+
+#endif /* _SDL_wsconsvideo_h */
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga.c
new file mode 100644
index 0000000..e1c0c2e
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga.c
@@ -0,0 +1,90 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is currently only used to enable DGA mouse.
+ There is a completely separate DGA driver that is fullscreen-only.
+*/
+
+#include "SDL_video.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_x11dga_c.h"
+
+/* Global for the error handler */
+int dga_event, dga_error = -1;
+
+void X11_EnableDGAMouse(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+ static int use_dgamouse = -1;
+
+ /* Check configuration to see if we should use DGA mouse */
+ if ( use_dgamouse < 0 ) {
+ int dga_major, dga_minor;
+ int dga_flags;
+ const char *env_use_dgamouse;
+
+ use_dgamouse = 1;
+ env_use_dgamouse = SDL_getenv("SDL_VIDEO_X11_DGAMOUSE");
+ if ( env_use_dgamouse ) {
+ use_dgamouse = SDL_atoi(env_use_dgamouse);
+ }
+ /* Check for buggy X servers */
+ if ( use_dgamouse && BUGGY_XFREE86(==, 4000) ) {
+ use_dgamouse = 0;
+ }
+ if ( !use_dgamouse || !local_X11 ||
+ !SDL_NAME(XF86DGAQueryExtension)(SDL_Display, &dga_event, &dga_error) ||
+ !SDL_NAME(XF86DGAQueryVersion)(SDL_Display, &dga_major, &dga_minor) ||
+ !SDL_NAME(XF86DGAQueryDirectVideo)(SDL_Display, SDL_Screen, &dga_flags) ||
+ !(dga_flags & XF86DGADirectPresent) ) {
+ use_dgamouse = 0;
+ }
+ }
+
+ if ( use_dgamouse && !(using_dga & DGA_MOUSE) ) {
+ if ( SDL_NAME(XF86DGADirectVideo)(SDL_Display, SDL_Screen, XF86DGADirectMouse) ) {
+ using_dga |= DGA_MOUSE;
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */
+}
+
+/* Argh. Glide resets DGA mouse mode when it makes the context current! */
+void X11_CheckDGAMouse(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+ if ( using_dga & DGA_MOUSE ) {
+ SDL_NAME(XF86DGADirectVideo)(SDL_Display,SDL_Screen,XF86DGADirectMouse);
+ }
+#endif
+}
+
+void X11_DisableDGAMouse(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+ if ( using_dga & DGA_MOUSE ) {
+ SDL_NAME(XF86DGADirectVideo)(SDL_Display, SDL_Screen, 0);
+ using_dga &= ~DGA_MOUSE;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */
+}
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga_c.h
new file mode 100644
index 0000000..a57511c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dga_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+
+/* Different DGA access states */
+#define DGA_GRAPHICS 0x01
+#define DGA_KEYBOARD 0x02
+#define DGA_MOUSE 0x04
+
+extern void X11_EnableDGAMouse(_THIS);
+extern void X11_CheckDGAMouse(_THIS);
+extern void X11_DisableDGAMouse(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c
new file mode 100644
index 0000000..7d4acbb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c
@@ -0,0 +1,223 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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 DEBUG_DYNAMIC_X11 0
+
+#include "SDL_x11dyn.h"
+
+#if DEBUG_DYNAMIC_X11
+#include <stdio.h>
+#endif
+
+#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+
+typedef struct
+{
+ void *lib;
+ const char *libname;
+} x11dynlib;
+
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
+#endif
+#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
+#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
+#endif
+
+static x11dynlib x11libs[] =
+{
+ { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC },
+ { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT },
+ { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER },
+ { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR },
+};
+
+static void *X11_GetSym(const char *fnname, int *rc)
+{
+ void *fn = NULL;
+ int i;
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].lib != NULL)
+ {
+ fn = SDL_LoadFunction(x11libs[i].lib, fnname);
+ if (fn != NULL)
+ break;
+ }
+ }
+
+ #if DEBUG_DYNAMIC_X11
+ if (fn != NULL)
+ printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn);
+ else
+ printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
+ #endif
+
+ if (fn == NULL)
+ *rc = 0; /* kill this module. */
+
+ return fn;
+}
+
+
+/* Define all the function pointers and wrappers... */
+#define SDL_X11_MODULE(modname)
+#define SDL_X11_SYM(rc,fn,params,args,ret) \
+ static rc (*p##fn) params = NULL; \
+ rc fn params { ret p##fn args ; }
+#include "SDL_x11sym.h"
+#undef SDL_X11_MODULE
+#undef SDL_X11_SYM
+#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
+
+/* Annoying varargs entry point... */
+#ifdef X_HAVE_UTF8_STRING
+XIC (*pXCreateIC)(XIM,...) = NULL;
+char *(*pXGetICValues)(XIC, ...) = NULL;
+#endif
+
+/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
+#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
+#define SDL_X11_SYM(rc,fn,params,args,ret)
+#include "SDL_x11sym.h"
+#undef SDL_X11_MODULE
+#undef SDL_X11_SYM
+
+
+static void *SDL_XGetRequest_workaround(Display* dpy, CARD8 type, size_t len)
+{
+ xReq *req;
+ WORD64ALIGN
+ if (dpy->bufptr + len > dpy->bufmax)
+ _XFlush(dpy);
+ dpy->last_req = dpy->bufptr;
+ req = (xReq*)dpy->bufptr;
+ req->reqType = type;
+ req->length = len / 4;
+ dpy->bufptr += len;
+ dpy->request++;
+ return req;
+}
+
+static int x11_load_refcount = 0;
+
+void SDL_X11_UnloadSymbols(void)
+{
+ #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+ /* Don't actually unload if more than one module is using the libs... */
+ if (x11_load_refcount > 0) {
+ if (--x11_load_refcount == 0) {
+ int i;
+
+ /* set all the function pointers to NULL. */
+ #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
+ #define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
+ #include "SDL_x11sym.h"
+ #undef SDL_X11_MODULE
+ #undef SDL_X11_SYM
+
+ #ifdef X_HAVE_UTF8_STRING
+ pXCreateIC = NULL;
+ pXGetICValues = NULL;
+ #endif
+
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].lib != NULL) {
+ SDL_UnloadObject(x11libs[i].lib);
+ x11libs[i].lib = NULL;
+ }
+ }
+ }
+ }
+ #endif
+}
+
+/* returns non-zero if all needed symbols were loaded. */
+int SDL_X11_LoadSymbols(void)
+{
+ int rc = 1; /* always succeed if not using Dynamic X11 stuff. */
+
+ #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+ /* deal with multiple modules (dga, x11, etc) needing these symbols... */
+ if (x11_load_refcount++ == 0) {
+ int i;
+ int *thismod = NULL;
+ for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
+ if (x11libs[i].libname != NULL) {
+ x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
+ }
+ }
+ #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
+ #define SDL_X11_SYM(rc,fn,params,args,ret) \
+ p##fn = (rc(*)params) X11_GetSym(#fn, thismod);
+ #include "SDL_x11sym.h"
+ #undef SDL_X11_MODULE
+ #undef SDL_X11_SYM
+
+ #ifdef X_HAVE_UTF8_STRING
+ pXCreateIC = (XIC(*)(XIM,...)) X11_GetSym("XCreateIC",
+ &SDL_X11_HAVE_UTF8);
+ pXGetICValues = (char * (*)(XIC,...)) X11_GetSym("XGetICValues",
+ &SDL_X11_HAVE_UTF8);
+ #endif
+
+ /*
+ * In case we're built with newer Xlib headers, we need to make sure
+ * that _XGetRequest() is available, even on older systems.
+ * Otherwise, various Xlib macros we use will call a NULL pointer.
+ */
+ if (!SDL_X11_HAVE_XGETREQUEST) {
+ p_XGetRequest = SDL_XGetRequest_workaround;
+ }
+
+ if (SDL_X11_HAVE_BASEXLIB) { /* all required symbols loaded. */
+ SDL_ClearError();
+ XInitThreads();
+ } else {
+ SDL_X11_UnloadSymbols(); /* in case something got loaded... */
+ rc = 0;
+ }
+ }
+ #else
+ #if DEBUG_DYNAMIC_X11
+ printf("X11: No dynamic X11 support in this build of SDL.\n");
+ #endif
+ #ifdef X_HAVE_UTF8_STRING
+ pXCreateIC = XCreateIC;
+ pXGetICValues = XGetICValues;
+ #endif
+ #endif
+
+ return rc;
+}
+
+/* end of SDL_x11dyn.c ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.h
new file mode 100644
index 0000000..c2ff82a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.h
@@ -0,0 +1,93 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_x11dyn_h
+#define _SDL_x11dyn_h
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+/* Apparently some X11 systems can't include this multiple times... */
+#ifndef SDL_INCLUDED_XLIBINT_H
+#define SDL_INCLUDED_XLIBINT_H 1
+#include <X11/Xlibint.h>
+#endif
+
+#include <X11/Xproto.h>
+
+#include "../Xext/extensions/Xext.h"
+#include "../Xext/extensions/extutil.h"
+
+#ifndef NO_SHARED_MEMORY
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+
+/*
+ * When using the "dynamic X11" functionality, we duplicate all the Xlib
+ * symbols that would be referenced by SDL inside of SDL itself.
+ * These duplicated symbols just serve as passthroughs to the functions
+ * in Xlib, that was dynamically loaded.
+ *
+ * This allows us to use Xlib as-is when linking against it directly, but
+ * also handles all the strange cases where there was code in the Xlib
+ * headers that may or may not exist or vary on a given platform.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* evil function signatures... */
+typedef Bool (*SDL_X11_XESetWireToEventRetType)(Display*,XEvent*,xEvent*);
+typedef int (*SDL_X11_XSynchronizeRetType)(Display*);
+typedef Status (*SDL_X11_XESetEventToWireRetType)(Display*,XEvent*,xEvent*);
+
+int SDL_X11_LoadSymbols(void);
+void SDL_X11_UnloadSymbols(void);
+
+/* That's really annoying...make this a function pointer no matter what. */
+#ifdef X_HAVE_UTF8_STRING
+extern XIC (*pXCreateIC)(XIM,...);
+extern char *(*pXGetICValues)(XIC, ...);
+#endif
+
+/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
+#define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname;
+#define SDL_X11_SYM(rc,fn,params,args,ret)
+#include "SDL_x11sym.h"
+#undef SDL_X11_MODULE
+#undef SDL_X11_SYM
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined _SDL_x11dyn_h */
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11events.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11events.c
new file mode 100644
index 0000000..559a001
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11events.c
@@ -0,0 +1,1414 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Handle the event stream, converting X11 events into SDL events */
+
+#include <setjmp.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#ifdef __SVR4
+#include <X11/Sunkeysym.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "SDL_timer.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11video.h"
+#include "SDL_x11dga_c.h"
+#include "SDL_x11modes_c.h"
+#include "SDL_x11image_c.h"
+#include "SDL_x11gamma_c.h"
+#include "SDL_x11wm_c.h"
+#include "SDL_x11mouse_c.h"
+#include "SDL_x11events_c.h"
+
+
+/* Define this if you want to debug X11 events */
+/*#define DEBUG_XEVENTS*/
+
+/* The translation tables from an X11 keysym to a SDL keysym */
+static SDLKey ODD_keymap[256];
+static SDLKey MISC_keymap[256];
+SDLKey X11_TranslateKeycode(Display *display, KeyCode kc);
+
+/*
+ Pending resize target for ConfigureNotify (so outdated events don't
+ cause inappropriate resize events)
+*/
+int X11_PendingConfigureNotifyWidth = -1;
+int X11_PendingConfigureNotifyHeight = -1;
+
+#ifdef X_HAVE_UTF8_STRING
+Uint32 Utf8ToUcs4(const Uint8 *utf8)
+{
+ Uint32 c;
+ int i = 1;
+ int noOctets = 0;
+ int firstOctetMask = 0;
+ unsigned char firstOctet = utf8[0];
+ if (firstOctet < 0x80) {
+ /*
+ Characters in the range:
+ 00000000 to 01111111 (ASCII Range)
+ are stored in one octet:
+ 0xxxxxxx (The same as its ASCII representation)
+ The least 6 significant bits of the first octet is the most 6 significant nonzero bits
+ of the UCS4 representation.
+ */
+ noOctets = 1;
+ firstOctetMask = 0x7F; /* 0(1111111) - The most significant bit is ignored */
+ } else if ((firstOctet & 0xE0) /* get the most 3 significant bits by AND'ing with 11100000 */
+ == 0xC0 ) { /* see if those 3 bits are 110. If so, the char is in this range */
+ /*
+ Characters in the range:
+ 00000000 10000000 to 00000111 11111111
+ are stored in two octets:
+ 110xxxxx 10xxxxxx
+ The least 5 significant bits of the first octet is the most 5 significant nonzero bits
+ of the UCS4 representation.
+ */
+ noOctets = 2;
+ firstOctetMask = 0x1F; /* 000(11111) - The most 3 significant bits are ignored */
+ } else if ((firstOctet & 0xF0) /* get the most 4 significant bits by AND'ing with 11110000 */
+ == 0xE0) { /* see if those 4 bits are 1110. If so, the char is in this range */
+ /*
+ Characters in the range:
+ 00001000 00000000 to 11111111 11111111
+ are stored in three octets:
+ 1110xxxx 10xxxxxx 10xxxxxx
+ The least 4 significant bits of the first octet is the most 4 significant nonzero bits
+ of the UCS4 representation.
+ */
+ noOctets = 3;
+ firstOctetMask = 0x0F; /* 0000(1111) - The most 4 significant bits are ignored */
+ } else if ((firstOctet & 0xF8) /* get the most 5 significant bits by AND'ing with 11111000 */
+ == 0xF0) { /* see if those 5 bits are 11110. If so, the char is in this range */
+ /*
+ Characters in the range:
+ 00000001 00000000 00000000 to 00011111 11111111 11111111
+ are stored in four octets:
+ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ The least 3 significant bits of the first octet is the most 3 significant nonzero bits
+ of the UCS4 representation.
+ */
+ noOctets = 4;
+ firstOctetMask = 0x07; /* 11110(111) - The most 5 significant bits are ignored */
+ } else if ((firstOctet & 0xFC) /* get the most 6 significant bits by AND'ing with 11111100 */
+ == 0xF8) { /* see if those 6 bits are 111110. If so, the char is in this range */
+ /*
+ Characters in the range:
+ 00000000 00100000 00000000 00000000 to
+ 00000011 11111111 11111111 11111111
+ are stored in five octets:
+ 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ The least 2 significant bits of the first octet is the most 2 significant nonzero bits
+ of the UCS4 representation.
+ */
+ noOctets = 5;
+ firstOctetMask = 0x03; /* 111110(11) - The most 6 significant bits are ignored */
+ } else if ((firstOctet & 0xFE) /* get the most 7 significant bits by AND'ing with 11111110 */
+ == 0xFC) { /* see if those 7 bits are 1111110. If so, the char is in this range */
+ /*
+ Characters in the range:
+ 00000100 00000000 00000000 00000000 to
+ 01111111 11111111 11111111 11111111
+ are stored in six octets:
+ 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ The least significant bit of the first octet is the most significant nonzero bit
+ of the UCS4 representation.
+ */
+ noOctets = 6;
+ firstOctetMask = 0x01; /* 1111110(1) - The most 7 significant bits are ignored */
+ } else
+ return 0; /* The given chunk is not a valid UTF-8 encoded Unicode character */
+
+ /*
+ The least noOctets significant bits of the first octet is the most 2 significant nonzero bits
+ of the UCS4 representation.
+ The first 6 bits of the UCS4 representation is the least 8-noOctets-1 significant bits of
+ firstOctet if the character is not ASCII. If so, it's the least 7 significant bits of firstOctet.
+ This done by AND'ing firstOctet with its mask to trim the bits used for identifying the
+ number of continuing octets (if any) and leave only the free bits (the x's)
+ Sample:
+ 1-octet: 0xxxxxxx & 01111111 = 0xxxxxxx
+ 2-octets: 110xxxxx & 00011111 = 000xxxxx
+ */
+ c = firstOctet & firstOctetMask;
+
+ /* Now, start filling c.ucs4 with the bits from the continuing octets from utf8. */
+ for (i = 1; i < noOctets; i++) {
+ /* A valid continuing octet is of the form 10xxxxxx */
+ if ((utf8[i] & 0xC0) /* get the most 2 significant bits by AND'ing with 11000000 */
+ != 0x80) /* see if those 2 bits are 10. If not, the is a malformed sequence. */
+ /*The given chunk is a partial sequence at the end of a string that could
+ begin a valid character */
+ return 0;
+
+ /* Make room for the next 6-bits */
+ c <<= 6;
+
+ /*
+ Take only the least 6 significance bits of the current octet (utf8[i]) and fill the created room
+ of c.ucs4 with them.
+ This done by AND'ing utf8[i] with 00111111 and the OR'ing the result with c.ucs4.
+ */
+ c |= utf8[i] & 0x3F;
+ }
+ return c;
+}
+
+/* Given a UTF-8 encoded string pointed to by utf8 of length length in
+ bytes, returns the corresponding UTF-16 encoded string in the
+ buffer pointed to by utf16. The maximum number of UTF-16 encoding
+ units (i.e., Unit16s) allowed in the buffer is specified in
+ utf16_max_length. The return value is the number of UTF-16
+ encoding units placed in the output buffer pointed to by utf16.
+
+ In case of an error, -1 is returned, leaving some unusable partial
+ results in the output buffer.
+
+ The caller must estimate the size of utf16 buffer by itself before
+ calling this function. Insufficient output buffer is considered as
+ an error, and once an error occured, this function doesn't give any
+ clue how large the result will be.
+
+ The error cases include following:
+
+ - Invalid byte sequences were in the input UTF-8 bytes. The caller
+ has no way to know what point in the input buffer was the
+ errornous byte.
+
+ - The input contained a character (a valid UTF-8 byte sequence)
+ whose scalar value exceeded the range that UTF-16 can represent
+ (i.e., characters whose Unicode scalar value above 0x110000).
+
+ - The output buffer has no enough space to hold entire utf16 data.
+
+ Please note:
+
+ - '\0'-termination is not assumed both on the input UTF-8 string
+ and on the output UTF-16 string; any legal zero byte in the input
+ UTF-8 string will be converted to a 16-bit zero in output. As a
+ side effect, the last UTF-16 encoding unit stored in the output
+ buffer will have a non-zero value if the input UTF-8 was not
+ '\0'-terminated.
+
+ - UTF-8 aliases are *not* considered as an error. They are
+ converted to UTF-16. For example, 0xC0 0xA0, 0xE0 0x80 0xA0,
+ and 0xF0 0x80 0x80 0xA0 are all mapped to a single UTF-16
+ encoding unit 0x0020.
+
+ - Three byte UTF-8 sequences whose value corresponds to a surrogate
+ code or other reserved scalar value are not considered as an
+ error either. They may cause an invalid UTF-16 data (e.g., those
+ containing unpaired surrogates).
+
+*/
+
+static int Utf8ToUtf16(const Uint8 *utf8, const int utf8_length, Uint16 *utf16, const int utf16_max_length) {
+
+ /* p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. */
+ Uint16 *p = utf16;
+ Uint16 const *const max_ptr = utf16 + utf16_max_length;
+
+ /* end_of_input points to the last byte of input as opposed to the next to the last byte. */
+ Uint8 const *const end_of_input = utf8 + utf8_length - 1;
+
+ while (utf8 <= end_of_input) {
+ Uint8 const c = *utf8;
+ if (p >= max_ptr) {
+ /* No more output space. */
+ return -1;
+ }
+ if (c < 0x80) {
+ /* One byte ASCII. */
+ *p++ = c;
+ utf8 += 1;
+ } else if (c < 0xC0) {
+ /* Follower byte without preceeding leader bytes. */
+ return -1;
+ } else if (c < 0xE0) {
+ /* Two byte sequence. We need one follower byte. */
+ if (end_of_input - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) {
+ return -1;
+ }
+ *p++ = (Uint16)(0xCF80 + (c << 6) + utf8[1]);
+ utf8 += 2;
+ } else if (c < 0xF0) {
+ /* Three byte sequence. We need two follower byte. */
+ if (end_of_input - utf8 < 2 || (((utf8[1] ^ 0x80) | (utf8[2] ^ 0x80)) & 0xC0)) {
+ return -1;
+ }
+ *p++ = (Uint16)(0xDF80 + (c << 12) + (utf8[1] << 6) + utf8[2]);
+ utf8 += 3;
+ } else if (c < 0xF8) {
+ int plane;
+ /* Four byte sequence. We need three follower bytes. */
+ if (end_of_input - utf8 < 3 || (((utf8[1] ^ 0x80) | (utf8[2] ^0x80) | (utf8[3] ^ 0x80)) & 0xC0)) {
+ return -1;
+ }
+ plane = (-0xC8 + (c << 2) + (utf8[1] >> 4));
+ if (plane == 0) {
+ /* This four byte sequence is an alias that
+ corresponds to a Unicode scalar value in BMP.
+ It fits in an UTF-16 encoding unit. */
+ *p++ = (Uint16)(0xDF80 + (utf8[1] << 12) + (utf8[2] << 6) + utf8[3]);
+ } else if (plane <= 16) {
+ /* This is a legal four byte sequence that corresponds to a surrogate pair. */
+ if (p + 1 >= max_ptr) {
+ /* No enough space on the output buffer for the pair. */
+ return -1;
+ }
+ *p++ = (Uint16)(0xE5B8 + (c << 8) + (utf8[1] << 2) + (utf8[2] >> 4));
+ *p++ = (Uint16)(0xDB80 + ((utf8[2] & 0x0F) << 6) + utf8[3]);
+ } else {
+ /* This four byte sequence is out of UTF-16 code space. */
+ return -1;
+ }
+ utf8 += 4;
+ } else {
+ /* Longer sequence or unused byte. */
+ return -1;
+ }
+ }
+ return p - utf16;
+}
+
+#endif
+
+/* Check to see if this is a repeated key.
+ (idea shamelessly lifted from GII -- thanks guys! :)
+ */
+static int X11_KeyRepeat(Display *display, XEvent *event)
+{
+ XEvent peekevent;
+ int repeated;
+
+ repeated = 0;
+ if ( XPending(display) ) {
+ XPeekEvent(display, &peekevent);
+ if ( (peekevent.type == KeyPress) &&
+ (peekevent.xkey.keycode == event->xkey.keycode) &&
+ ((peekevent.xkey.time-event->xkey.time) < 2) ) {
+ repeated = 1;
+ XNextEvent(display, &peekevent);
+ }
+ }
+ return(repeated);
+}
+
+/* Note: The X server buffers and accumulates mouse motion events, so
+ the motion event generated by the warp may not appear exactly as we
+ expect it to. We work around this (and improve performance) by only
+ warping the pointer when it reaches the edge, and then wait for it.
+*/
+#define MOUSE_FUDGE_FACTOR 8
+
+static __inline__ int X11_WarpedMotion(_THIS, XEvent *xevent)
+{
+ int w, h, i;
+ int deltax, deltay;
+ int posted;
+
+ w = SDL_VideoSurface->w;
+ h = SDL_VideoSurface->h;
+ deltax = xevent->xmotion.x - mouse_last.x;
+ deltay = xevent->xmotion.y - mouse_last.y;
+#ifdef DEBUG_MOTION
+ printf("Warped mouse motion: %d,%d\n", deltax, deltay);
+#endif
+ mouse_last.x = xevent->xmotion.x;
+ mouse_last.y = xevent->xmotion.y;
+ posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay);
+
+ if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) ||
+ (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) ||
+ (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) ||
+ (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) {
+ /* Get the events that have accumulated */
+ while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) {
+ deltax = xevent->xmotion.x - mouse_last.x;
+ deltay = xevent->xmotion.y - mouse_last.y;
+#ifdef DEBUG_MOTION
+ printf("Extra mouse motion: %d,%d\n", deltax, deltay);
+#endif
+ mouse_last.x = xevent->xmotion.x;
+ mouse_last.y = xevent->xmotion.y;
+ posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay);
+ }
+ mouse_last.x = w/2;
+ mouse_last.y = h/2;
+ XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0,
+ mouse_last.x, mouse_last.y);
+ for ( i=0; i<10; ++i ) {
+ XMaskEvent(SDL_Display, PointerMotionMask, xevent);
+ if ( (xevent->xmotion.x >
+ (mouse_last.x-MOUSE_FUDGE_FACTOR)) &&
+ (xevent->xmotion.x <
+ (mouse_last.x+MOUSE_FUDGE_FACTOR)) &&
+ (xevent->xmotion.y >
+ (mouse_last.y-MOUSE_FUDGE_FACTOR)) &&
+ (xevent->xmotion.y <
+ (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) {
+ break;
+ }
+#ifdef DEBUG_XEVENTS
+ printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y);
+#endif
+ }
+#ifdef DEBUG_XEVENTS
+ if ( i == 10 ) {
+ printf("Warning: didn't detect mouse warp motion\n");
+ }
+#endif
+ }
+ return(posted);
+}
+
+static int X11_DispatchEvent(_THIS)
+{
+ int posted;
+ XEvent xevent;
+
+ SDL_memset(&xevent, '\0', sizeof (XEvent)); /* valgrind fix. --ryan. */
+ XNextEvent(SDL_Display, &xevent);
+
+ /* Discard KeyRelease and KeyPress events generated by auto-repeat.
+ We need to do it before passing event to XFilterEvent. Otherwise,
+ KeyRelease aware IMs are confused... */
+ if ( xevent.type == KeyRelease
+ && X11_KeyRepeat(SDL_Display, &xevent) ) {
+ return 0;
+ }
+
+#ifdef X_HAVE_UTF8_STRING
+ /* If we are translating with IM, we need to pass all events
+ to XFilterEvent, and discard those filtered events immediately. */
+ if ( SDL_TranslateUNICODE
+ && SDL_IM != NULL
+ && XFilterEvent(&xevent, None) ) {
+ return 0;
+ }
+#endif
+
+ posted = 0;
+ switch (xevent.type) {
+
+ /* Gaining mouse coverage? */
+ case EnterNotify: {
+#ifdef DEBUG_XEVENTS
+printf("EnterNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y);
+if ( xevent.xcrossing.mode == NotifyGrab )
+printf("Mode: NotifyGrab\n");
+if ( xevent.xcrossing.mode == NotifyUngrab )
+printf("Mode: NotifyUngrab\n");
+#endif
+ if ( this->input_grab == SDL_GRAB_OFF ) {
+ posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ }
+ posted = SDL_PrivateMouseMotion(0, 0,
+ xevent.xcrossing.x,
+ xevent.xcrossing.y);
+ }
+ break;
+
+ /* Losing mouse coverage? */
+ case LeaveNotify: {
+#ifdef DEBUG_XEVENTS
+printf("LeaveNotify! (%d,%d)\n", xevent.xcrossing.x, xevent.xcrossing.y);
+if ( xevent.xcrossing.mode == NotifyGrab )
+printf("Mode: NotifyGrab\n");
+if ( xevent.xcrossing.mode == NotifyUngrab )
+printf("Mode: NotifyUngrab\n");
+#endif
+ if ( (xevent.xcrossing.mode != NotifyGrab) &&
+ (xevent.xcrossing.mode != NotifyUngrab) &&
+ (xevent.xcrossing.detail != NotifyInferior) ) {
+ if ( this->input_grab == SDL_GRAB_OFF ) {
+ posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ } else {
+ posted = SDL_PrivateMouseMotion(0, 0,
+ xevent.xcrossing.x,
+ xevent.xcrossing.y);
+ }
+ }
+ }
+ break;
+
+ /* Gaining input focus? */
+ case FocusIn: {
+#ifdef DEBUG_XEVENTS
+printf("FocusIn!\n");
+#endif
+ posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+
+#ifdef X_HAVE_UTF8_STRING
+ if ( SDL_IC != NULL ) {
+ XSetICFocus(SDL_IC);
+ }
+#endif
+ /* Queue entry into fullscreen mode */
+ switch_waiting = 0x01 | SDL_FULLSCREEN;
+ switch_time = SDL_GetTicks() + 1500;
+ }
+ break;
+
+ /* Losing input focus? */
+ case FocusOut: {
+#ifdef DEBUG_XEVENTS
+printf("FocusOut!\n");
+#endif
+ posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+
+#ifdef X_HAVE_UTF8_STRING
+ if ( SDL_IC != NULL ) {
+ XUnsetICFocus(SDL_IC);
+ }
+#endif
+ /* Queue leaving fullscreen mode */
+ switch_waiting = 0x01;
+ switch_time = SDL_GetTicks() + 200;
+ }
+ break;
+
+#ifdef X_HAVE_UTF8_STRING
+ /* Some IM requires MappingNotify to be passed to
+ XRefreshKeyboardMapping by the app. */
+ case MappingNotify: {
+ XRefreshKeyboardMapping(&xevent.xmapping);
+ }
+ break;
+#endif /* X_HAVE_UTF8_STRING */
+
+ /* Generated upon EnterWindow and FocusIn */
+ case KeymapNotify: {
+#ifdef DEBUG_XEVENTS
+printf("KeymapNotify!\n");
+#endif
+ X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
+ }
+ break;
+
+ /* Mouse motion? */
+ case MotionNotify: {
+ if ( SDL_VideoSurface ) {
+ if ( mouse_relative ) {
+ if ( using_dga & DGA_MOUSE ) {
+#ifdef DEBUG_MOTION
+ printf("DGA motion: %d,%d\n", xevent.xmotion.x_root, xevent.xmotion.y_root);
+#endif
+ posted = SDL_PrivateMouseMotion(0, 1,
+ xevent.xmotion.x_root,
+ xevent.xmotion.y_root);
+ } else {
+ posted = X11_WarpedMotion(this,&xevent);
+ }
+ } else {
+#ifdef DEBUG_MOTION
+ printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
+#endif
+ posted = SDL_PrivateMouseMotion(0, 0,
+ xevent.xmotion.x,
+ xevent.xmotion.y);
+ }
+ }
+ }
+ break;
+
+ /* Mouse button press? */
+ case ButtonPress: {
+ posted = SDL_PrivateMouseButton(SDL_PRESSED,
+ xevent.xbutton.button, 0, 0);
+ }
+ break;
+
+ /* Mouse button release? */
+ case ButtonRelease: {
+ posted = SDL_PrivateMouseButton(SDL_RELEASED,
+ xevent.xbutton.button, 0, 0);
+ }
+ break;
+
+ /* Key press? */
+ case KeyPress: {
+ SDL_keysym keysym;
+ KeyCode keycode = xevent.xkey.keycode;
+
+#ifdef DEBUG_XEVENTS
+printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
+#endif
+ /* If we're not doing translation, we're done! */
+ if ( !SDL_TranslateUNICODE ) {
+ /* Get the translated SDL virtual keysym and put it on the queue.*/
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ break;
+ }
+
+ /* Look up the translated value for the key event */
+#ifdef X_HAVE_UTF8_STRING
+ if ( SDL_IC != NULL ) {
+ Status status;
+ KeySym xkeysym;
+ int i;
+ /* A UTF-8 character can be at most 6 bytes */
+ /* ... It's true, but Xutf8LookupString can
+ return more than one characters. Moreover,
+ the spec. put no upper bound, so we should
+ be ready for longer strings. */
+ char keybuf[32];
+ char *keydata = keybuf;
+ int count;
+ Uint16 utf16buf[32];
+ Uint16 *utf16data = utf16buf;
+ int utf16size;
+ int utf16length;
+
+ count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, sizeof(keybuf), &xkeysym, &status);
+ if (XBufferOverflow == status) {
+ /* The IM has just generated somewhat long
+ string. We need a longer buffer in this
+ case. */
+ keydata = SDL_malloc(count);
+ if ( keydata == NULL ) {
+ SDL_OutOfMemory();
+ break;
+ }
+ count = Xutf8LookupString(SDL_IC, &xevent.xkey, keydata, count, &xkeysym, &status);
+ }
+
+ switch (status) {
+
+ case XBufferOverflow: {
+ /* Oops! We have allocated the bytes as
+ requested by Xutf8LookupString, so the
+ length of the buffer must be
+ sufficient. This case should never
+ happen! */
+ SDL_SetError("Xutf8LookupString indicated a double buffer overflow!");
+ break;
+ }
+
+ case XLookupChars:
+ case XLookupBoth: {
+ if (0 == count) {
+ break;
+ }
+
+ /* We got a converted string from IM. Make
+ sure to deliver all characters to the
+ application as SDL events. Note that
+ an SDL event can only carry one UTF-16
+ encoding unit, and a surrogate pair is
+ delivered as two SDL events. I guess
+ this behaviour is probably _imported_
+ from Windows or MacOS. To do so, we need
+ to convert the UTF-8 data into UTF-16
+ data (not UCS4/UTF-32!). We need an
+ estimate of the number of UTF-16 encoding
+ units here. The worst case is pure ASCII
+ string. Assume so. */
+ /* In 1.3 SDL may have a text event instead, that
+ carries the whole UTF-8 string with it. */
+ utf16size = count * sizeof(Uint16);
+ if (utf16size > sizeof(utf16buf)) {
+ utf16data = (Uint16 *) SDL_malloc(utf16size);
+ if (utf16data == NULL) {
+ SDL_OutOfMemory();
+ break;
+ }
+ }
+ utf16length = Utf8ToUtf16((Uint8 *)keydata, count, utf16data, utf16size);
+ if (utf16length < 0) {
+ /* The keydata contained an invalid byte
+ sequence. It should be a bug of the IM
+ or Xlib... */
+ SDL_SetError("Oops! Xutf8LookupString returned an invalid UTF-8 sequence!");
+ break;
+ }
+
+ /* Deliver all UTF-16 encoding units. At
+ this moment, SDL event queue has a
+ fixed size (128 events), and an SDL
+ event can hold just one UTF-16 encoding
+ unit. So, if we receive more than 128
+ UTF-16 encoding units from a commit,
+ exceeded characters will be lost. */
+ for (i = 0; i < utf16length - 1; i++) {
+ keysym.scancode = 0;
+ keysym.sym = SDLK_UNKNOWN;
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = utf16data[i];
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ /* The keysym for the last character carries the
+ scancode and symbol that corresponds to the X11
+ keycode. */
+ if (utf16length > 0) {
+ keysym.scancode = keycode;
+ keysym.sym = (keycode ? X11_TranslateKeycode(SDL_Display, keycode) : 0);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = utf16data[utf16length - 1];
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ break;
+ }
+
+ case XLookupKeySym: {
+ /* I'm not sure whether it is possible that
+ a zero keycode makes XLookupKeySym
+ status. What I'm sure is that a
+ combination of a zero scan code and a non
+ zero sym makes SDL_PrivateKeyboard
+ strange state... So, just discard it.
+ If this doesn't work, I'm receiving bug
+ reports, and I can know under what
+ condition this case happens. */
+ if (keycode) {
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ break;
+ }
+
+ case XLookupNone: {
+ /* IM has eaten the event. */
+ break;
+ }
+
+ default:
+ /* An unknown status from Xutf8LookupString. */
+ SDL_SetError("Oops! Xutf8LookupStringreturned an unknown status");
+ }
+
+ /* Release dynamic buffers if allocated. */
+ if (keydata != NULL && keybuf != keydata) {
+ SDL_free(keydata);
+ }
+ if (utf16data != NULL && utf16buf != utf16data) {
+ SDL_free(utf16data);
+ }
+ }
+ else
+#endif
+ {
+ static XComposeStatus state;
+ char keybuf[32];
+
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+ if ( XLookupString(&xevent.xkey,
+ keybuf, sizeof(keybuf),
+ NULL, &state) ) {
+ /*
+ * FIXME: XLookupString() may yield more than one
+ * character, so we need a mechanism to allow for
+ * this (perhaps null keypress events with a
+ * unicode value)
+ */
+ keysym.unicode = (Uint8)keybuf[0];
+ }
+
+ posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
+ }
+ }
+ break;
+
+ /* Key release? */
+ case KeyRelease: {
+ SDL_keysym keysym;
+ KeyCode keycode = xevent.xkey.keycode;
+
+ if (keycode == 0) {
+ /* There should be no KeyRelease for keycode == 0,
+ since it is a notification from IM but a real
+ keystroke. */
+ /* We need to emit some diagnostic message here. */
+ break;
+ }
+
+#ifdef DEBUG_XEVENTS
+printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
+#endif
+
+ /* Get the translated SDL virtual keysym */
+ keysym.scancode = keycode;
+ keysym.sym = X11_TranslateKeycode(SDL_Display, keycode);
+ keysym.mod = KMOD_NONE;
+ keysym.unicode = 0;
+
+ posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
+ }
+ break;
+
+ /* Have we been iconified? */
+ case UnmapNotify: {
+#ifdef DEBUG_XEVENTS
+printf("UnmapNotify!\n");
+#endif
+ /* If we're active, make ourselves inactive */
+ if ( SDL_GetAppState() & SDL_APPACTIVE ) {
+ /* Swap out the gamma before we go inactive */
+ X11_SwapVidModeGamma(this);
+
+ /* Send an internal deactivate event */
+ posted = SDL_PrivateAppActive(0,
+ SDL_APPACTIVE|SDL_APPINPUTFOCUS);
+ }
+ }
+ break;
+
+ /* Have we been restored? */
+ case MapNotify: {
+#ifdef DEBUG_XEVENTS
+printf("MapNotify!\n");
+#endif
+ /* If we're not active, make ourselves active */
+ if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) {
+ /* Send an internal activate event */
+ posted = SDL_PrivateAppActive(1, SDL_APPACTIVE);
+
+ /* Now that we're active, swap the gamma back */
+ X11_SwapVidModeGamma(this);
+ }
+
+ if ( SDL_VideoSurface &&
+ (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) {
+ X11_EnterFullScreen(this);
+ } else {
+ X11_GrabInputNoLock(this, this->input_grab);
+ }
+ X11_CheckMouseModeNoLock(this);
+
+ if ( SDL_VideoSurface ) {
+ X11_RefreshDisplay(this);
+ }
+ }
+ break;
+
+ /* Have we been resized or moved? */
+ case ConfigureNotify: {
+#ifdef DEBUG_XEVENTS
+printf("ConfigureNotify! (resize: %dx%d)\n", xevent.xconfigure.width, xevent.xconfigure.height);
+#endif
+ if ((X11_PendingConfigureNotifyWidth != -1) &&
+ (X11_PendingConfigureNotifyHeight != -1)) {
+ if ((xevent.xconfigure.width != X11_PendingConfigureNotifyWidth) &&
+ (xevent.xconfigure.height != X11_PendingConfigureNotifyHeight)) {
+ /* Event is from before the resize, so ignore. */
+ break;
+ }
+ X11_PendingConfigureNotifyWidth = -1;
+ X11_PendingConfigureNotifyHeight = -1;
+ }
+ if ( SDL_VideoSurface ) {
+ if ((xevent.xconfigure.width != SDL_VideoSurface->w) ||
+ (xevent.xconfigure.height != SDL_VideoSurface->h)) {
+ /* FIXME: Find a better fix for the bug with KDE 1.2 */
+ if ( ! ((xevent.xconfigure.width == 32) &&
+ (xevent.xconfigure.height == 32)) ) {
+ SDL_PrivateResize(xevent.xconfigure.width,
+ xevent.xconfigure.height);
+ }
+ } else {
+ /* OpenGL windows need to know about the change */
+ if ( SDL_VideoSurface->flags & SDL_OPENGL ) {
+ SDL_PrivateExpose();
+ }
+ }
+ }
+ }
+ break;
+
+ /* Have we been requested to quit (or another client message?) */
+ case ClientMessage: {
+ if ( (xevent.xclient.format == 32) &&
+ (xevent.xclient.data.l[0] == WM_DELETE_WINDOW) )
+ {
+ posted = SDL_PrivateQuit();
+ } else
+ if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_X11;
+ wmmsg.event.xevent = xevent;
+ posted = SDL_PrivateSysWMEvent(&wmmsg);
+ }
+ }
+ break;
+
+ /* Do we need to refresh ourselves? */
+ case Expose: {
+#ifdef DEBUG_XEVENTS
+printf("Expose (count = %d)\n", xevent.xexpose.count);
+#endif
+ if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) {
+ X11_RefreshDisplay(this);
+ }
+ }
+ break;
+
+ default: {
+#ifdef DEBUG_XEVENTS
+printf("Unhandled event %d\n", xevent.type);
+#endif
+ /* Only post the event if we're watching for it */
+ if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
+ SDL_SysWMmsg wmmsg;
+
+ SDL_VERSION(&wmmsg.version);
+ wmmsg.subsystem = SDL_SYSWM_X11;
+ wmmsg.event.xevent = xevent;
+ posted = SDL_PrivateSysWMEvent(&wmmsg);
+ }
+ }
+ break;
+ }
+ return(posted);
+}
+
+/* Ack! XPending() actually performs a blocking read if no events available */
+int X11_Pending(Display *display)
+{
+ /* Flush the display connection and look to see if events are queued */
+ XFlush(display);
+ if ( XEventsQueued(display, QueuedAlready) ) {
+ return(1);
+ }
+
+ /* More drastic measures are required -- see if X is ready to talk */
+ {
+ static struct timeval zero_time; /* static == 0 */
+ int x11_fd;
+ fd_set fdset;
+
+ x11_fd = ConnectionNumber(display);
+ FD_ZERO(&fdset);
+ FD_SET(x11_fd, &fdset);
+ if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) {
+ return(XPending(display));
+ }
+ }
+
+ /* Oh well, nothing is ready .. */
+ return(0);
+}
+
+void X11_PumpEvents(_THIS)
+{
+ int pending;
+
+ /* Update activity every five seconds to prevent screensaver. --ryan. */
+ if (!allow_screensaver) {
+ static Uint32 screensaverTicks;
+ Uint32 nowTicks = SDL_GetTicks();
+ if ((nowTicks - screensaverTicks) > 5000) {
+ XResetScreenSaver(SDL_Display);
+ screensaverTicks = nowTicks;
+ }
+ }
+
+ /* Keep processing pending events */
+ pending = 0;
+ while ( X11_Pending(SDL_Display) ) {
+ X11_DispatchEvent(this);
+ ++pending;
+ }
+ if ( switch_waiting ) {
+ Uint32 now;
+
+ now = SDL_GetTicks();
+ if ( pending || !SDL_VideoSurface ) {
+ /* Try again later... */
+ if ( switch_waiting & SDL_FULLSCREEN ) {
+ switch_time = now + 1500;
+ } else {
+ switch_time = now + 200;
+ }
+ } else if ( (int)(switch_time-now) <= 0 ) {
+ Uint32 go_fullscreen;
+
+ go_fullscreen = switch_waiting & SDL_FULLSCREEN;
+ switch_waiting = 0;
+ if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) {
+ if ( go_fullscreen ) {
+ X11_EnterFullScreen(this);
+ } else {
+ X11_LeaveFullScreen(this);
+ }
+ }
+ /* Handle focus in/out when grabbed */
+ if ( go_fullscreen ) {
+ X11_GrabInputNoLock(this, this->input_grab);
+ } else {
+ X11_GrabInputNoLock(this, SDL_GRAB_OFF);
+ }
+ X11_CheckMouseModeNoLock(this);
+ }
+ }
+}
+
+void X11_InitKeymap(void)
+{
+ int i;
+
+ /* Odd keys used in international keyboards */
+ for ( i=0; i<SDL_arraysize(ODD_keymap); ++i )
+ ODD_keymap[i] = SDLK_UNKNOWN;
+
+ /* Some of these might be mappable to an existing SDLK_ code */
+ ODD_keymap[XK_dead_grave&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_acute&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_tilde&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_macron&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_breve&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_abovedot&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_diaeresis&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_abovering&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_doubleacute&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_caron&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_cedilla&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_ogonek&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_iota&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_voiced_sound&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_semivoiced_sound&0xFF] = SDLK_COMPOSE;
+ ODD_keymap[XK_dead_belowdot&0xFF] = SDLK_COMPOSE;
+#ifdef XK_dead_hook
+ ODD_keymap[XK_dead_hook&0xFF] = SDLK_COMPOSE;
+#endif
+#ifdef XK_dead_horn
+ ODD_keymap[XK_dead_horn&0xFF] = SDLK_COMPOSE;
+#endif
+
+#ifdef XK_dead_circumflex
+ /* These X keysyms have 0xFE as the high byte */
+ ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET;
+#endif
+#ifdef XK_ISO_Level3_Shift
+ ODD_keymap[XK_ISO_Level3_Shift&0xFF] = SDLK_MODE; /* "Alt Gr" key */
+#endif
+
+ /* Map the miscellaneous keys */
+ for ( i=0; i<SDL_arraysize(MISC_keymap); ++i )
+ MISC_keymap[i] = SDLK_UNKNOWN;
+
+ /* These X keysyms have 0xFF as the high byte */
+ MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE;
+ MISC_keymap[XK_Tab&0xFF] = SDLK_TAB;
+ MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR;
+ MISC_keymap[XK_Return&0xFF] = SDLK_RETURN;
+ MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE;
+ MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE;
+ MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE;
+
+ MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */
+ MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1;
+ MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2;
+ MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3;
+ MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4;
+ MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5;
+ MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6;
+ MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7;
+ MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8;
+ MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9;
+ MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0;
+ MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1;
+ MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2;
+ MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3;
+ MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4;
+ MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5;
+ MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6;
+ MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7;
+ MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8;
+ MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9;
+ MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD;
+ MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
+ MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
+ MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
+ MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS;
+ MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS;
+ MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER;
+ MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS;
+
+ MISC_keymap[XK_Up&0xFF] = SDLK_UP;
+ MISC_keymap[XK_Down&0xFF] = SDLK_DOWN;
+ MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT;
+ MISC_keymap[XK_Left&0xFF] = SDLK_LEFT;
+ MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT;
+ MISC_keymap[XK_Home&0xFF] = SDLK_HOME;
+ MISC_keymap[XK_End&0xFF] = SDLK_END;
+ MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP;
+ MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN;
+
+ MISC_keymap[XK_F1&0xFF] = SDLK_F1;
+ MISC_keymap[XK_F2&0xFF] = SDLK_F2;
+ MISC_keymap[XK_F3&0xFF] = SDLK_F3;
+ MISC_keymap[XK_F4&0xFF] = SDLK_F4;
+ MISC_keymap[XK_F5&0xFF] = SDLK_F5;
+ MISC_keymap[XK_F6&0xFF] = SDLK_F6;
+ MISC_keymap[XK_F7&0xFF] = SDLK_F7;
+ MISC_keymap[XK_F8&0xFF] = SDLK_F8;
+ MISC_keymap[XK_F9&0xFF] = SDLK_F9;
+ MISC_keymap[XK_F10&0xFF] = SDLK_F10;
+ MISC_keymap[XK_F11&0xFF] = SDLK_F11;
+ MISC_keymap[XK_F12&0xFF] = SDLK_F12;
+ MISC_keymap[XK_F13&0xFF] = SDLK_F13;
+ MISC_keymap[XK_F14&0xFF] = SDLK_F14;
+ MISC_keymap[XK_F15&0xFF] = SDLK_F15;
+
+ MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK;
+ MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
+ MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
+ MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT;
+ MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT;
+ MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL;
+ MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL;
+ MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT;
+ MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT;
+ MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA;
+ MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA;
+ MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */
+ MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */
+ MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */
+ MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */
+
+ MISC_keymap[XK_Help&0xFF] = SDLK_HELP;
+ MISC_keymap[XK_Print&0xFF] = SDLK_PRINT;
+ MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ;
+ MISC_keymap[XK_Break&0xFF] = SDLK_BREAK;
+ MISC_keymap[XK_Menu&0xFF] = SDLK_MENU;
+ MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */
+}
+
+/* Get the translated SDL virtual keysym */
+SDLKey X11_TranslateKeycode(Display *display, KeyCode kc)
+{
+ KeySym xsym;
+ SDLKey key;
+
+ xsym = XKeycodeToKeysym(display, kc, 0);
+#ifdef DEBUG_KEYS
+ fprintf(stderr, "Translating key code %d -> 0x%.4x\n", kc, xsym);
+#endif
+ key = SDLK_UNKNOWN;
+ if ( xsym ) {
+ switch (xsym>>8) {
+ case 0x1005FF:
+#ifdef SunXK_F36
+ if ( xsym == SunXK_F36 )
+ key = SDLK_F11;
+#endif
+#ifdef SunXK_F37
+ if ( xsym == SunXK_F37 )
+ key = SDLK_F12;
+#endif
+ break;
+ case 0x00: /* Latin 1 */
+ key = (SDLKey)(xsym & 0xFF);
+ break;
+ case 0x01: /* Latin 2 */
+ case 0x02: /* Latin 3 */
+ case 0x03: /* Latin 4 */
+ case 0x04: /* Katakana */
+ case 0x05: /* Arabic */
+ case 0x06: /* Cyrillic */
+ case 0x07: /* Greek */
+ case 0x08: /* Technical */
+ case 0x0A: /* Publishing */
+ case 0x0C: /* Hebrew */
+ case 0x0D: /* Thai */
+ /* These are wrong, but it's better than nothing */
+ key = (SDLKey)(xsym & 0xFF);
+ break;
+ case 0xFE:
+ key = ODD_keymap[xsym&0xFF];
+ break;
+ case 0xFF:
+ key = MISC_keymap[xsym&0xFF];
+ break;
+ default:
+ /*
+ fprintf(stderr, "X11: Unhandled xsym, sym = 0x%04x\n",
+ (unsigned int)xsym);
+ */
+ break;
+ }
+ } else {
+ /* X11 doesn't know how to translate the key! */
+ switch (kc) {
+ /* Caution:
+ These keycodes are from the Microsoft Keyboard
+ */
+ case 115:
+ key = SDLK_LSUPER;
+ break;
+ case 116:
+ key = SDLK_RSUPER;
+ break;
+ case 117:
+ key = SDLK_MENU;
+ break;
+ default:
+ /*
+ * no point in an error message; happens for
+ * several keys when we get a keymap notify
+ */
+ break;
+ }
+ }
+ return key;
+}
+
+/* X11 modifier masks for various keys */
+static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask;
+static unsigned num_mask, mode_switch_mask;
+
+static void get_modifier_masks(Display *display)
+{
+ static unsigned got_masks;
+ int i, j;
+ XModifierKeymap *xmods;
+ unsigned n;
+
+ if(got_masks)
+ return;
+
+ xmods = XGetModifierMapping(display);
+ n = xmods->max_keypermod;
+ for(i = 3; i < 8; i++) {
+ for(j = 0; j < n; j++) {
+ KeyCode kc = xmods->modifiermap[i * n + j];
+ KeySym ks = XKeycodeToKeysym(display, kc, 0);
+ unsigned mask = 1 << i;
+ switch(ks) {
+ case XK_Num_Lock:
+ num_mask = mask; break;
+ case XK_Alt_L:
+ alt_l_mask = mask; break;
+ case XK_Alt_R:
+ alt_r_mask = mask; break;
+ case XK_Meta_L:
+ meta_l_mask = mask; break;
+ case XK_Meta_R:
+ meta_r_mask = mask; break;
+ case XK_Mode_switch:
+ mode_switch_mask = mask; break;
+ }
+ }
+ }
+ XFreeModifiermap(xmods);
+ got_masks = 1;
+}
+
+
+/*
+ * This function is semi-official; it is not officially exported and should
+ * not be considered part of the SDL API, but may be used by client code
+ * that *really* needs it (including legacy code).
+ * It is slow, though, and should be avoided if possible.
+ *
+ * Note that it isn't completely accurate either; in particular, multi-key
+ * sequences (dead accents, compose key sequences) will not work since the
+ * state has been irrevocably lost.
+ */
+Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers)
+{
+ struct SDL_VideoDevice *this = current_video;
+ char keybuf[32];
+ int i;
+ KeySym xsym = 0;
+ XKeyEvent xkey;
+ Uint16 unicode;
+
+ if ( !this || !SDL_Display ) {
+ return 0;
+ }
+
+ SDL_memset(&xkey, 0, sizeof(xkey));
+ xkey.display = SDL_Display;
+
+ xsym = keysym; /* last resort if not found */
+ for (i = 0; i < 256; ++i) {
+ if ( MISC_keymap[i] == keysym ) {
+ xsym = 0xFF00 | i;
+ break;
+ } else if ( ODD_keymap[i] == keysym ) {
+ xsym = 0xFE00 | i;
+ break;
+ }
+ }
+
+ xkey.keycode = XKeysymToKeycode(xkey.display, xsym);
+
+ get_modifier_masks(SDL_Display);
+ if(modifiers & KMOD_SHIFT)
+ xkey.state |= ShiftMask;
+ if(modifiers & KMOD_CAPS)
+ xkey.state |= LockMask;
+ if(modifiers & KMOD_CTRL)
+ xkey.state |= ControlMask;
+ if(modifiers & KMOD_MODE)
+ xkey.state |= mode_switch_mask;
+ if(modifiers & KMOD_LALT)
+ xkey.state |= alt_l_mask;
+ if(modifiers & KMOD_RALT)
+ xkey.state |= alt_r_mask;
+ if(modifiers & KMOD_LMETA)
+ xkey.state |= meta_l_mask;
+ if(modifiers & KMOD_RMETA)
+ xkey.state |= meta_r_mask;
+ if(modifiers & KMOD_NUM)
+ xkey.state |= num_mask;
+
+ unicode = 0;
+ if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) )
+ unicode = (unsigned char)keybuf[0];
+ return(unicode);
+}
+
+
+/*
+ * Called when focus is regained, to read the keyboard state and generate
+ * synthetic keypress/release events.
+ * key_vec is a bit vector of keycodes (256 bits)
+ */
+void X11_SetKeyboardState(Display *display, const char *key_vec)
+{
+ char keys_return[32];
+ int i;
+ Uint8 *kstate = SDL_GetKeyState(NULL);
+ SDLMod modstate;
+ Window junk_window;
+ int x, y;
+ unsigned int mask;
+
+ /* The first time the window is mapped, we initialize key state */
+ if ( ! key_vec ) {
+ XQueryKeymap(display, keys_return);
+ key_vec = keys_return;
+ }
+
+ /* Get the keyboard modifier state */
+ modstate = 0;
+ get_modifier_masks(display);
+ if ( XQueryPointer(display, DefaultRootWindow(display),
+ &junk_window, &junk_window, &x, &y, &x, &y, &mask) ) {
+ if ( mask & LockMask ) {
+ modstate |= KMOD_CAPS;
+ }
+ if ( mask & mode_switch_mask ) {
+ modstate |= KMOD_MODE;
+ }
+ if ( mask & num_mask ) {
+ modstate |= KMOD_NUM;
+ }
+ }
+
+ /* Zero the new keyboard state and generate it */
+ SDL_memset(kstate, 0, SDLK_LAST);
+ /*
+ * An obvious optimisation is to check entire longwords at a time in
+ * both loops, but we can't be sure the arrays are aligned so it's not
+ * worth the extra complexity
+ */
+ for ( i = 0; i < 32; i++ ) {
+ int j;
+ if ( !key_vec[i] )
+ continue;
+ for ( j = 0; j < 8; j++ ) {
+ if ( key_vec[i] & (1 << j) ) {
+ SDLKey key;
+ KeyCode kc = (i << 3 | j);
+ key = X11_TranslateKeycode(display, kc);
+ if ( key == SDLK_UNKNOWN ) {
+ continue;
+ }
+ kstate[key] = SDL_PRESSED;
+ switch (key) {
+ case SDLK_LSHIFT:
+ modstate |= KMOD_LSHIFT;
+ break;
+ case SDLK_RSHIFT:
+ modstate |= KMOD_RSHIFT;
+ break;
+ case SDLK_LCTRL:
+ modstate |= KMOD_LCTRL;
+ break;
+ case SDLK_RCTRL:
+ modstate |= KMOD_RCTRL;
+ break;
+ case SDLK_LALT:
+ modstate |= KMOD_LALT;
+ break;
+ case SDLK_RALT:
+ modstate |= KMOD_RALT;
+ break;
+ case SDLK_LMETA:
+ modstate |= KMOD_LMETA;
+ break;
+ case SDLK_RMETA:
+ modstate |= KMOD_RMETA;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ /* Hack - set toggle key state */
+ if ( modstate & KMOD_CAPS ) {
+ kstate[SDLK_CAPSLOCK] = SDL_PRESSED;
+ } else {
+ kstate[SDLK_CAPSLOCK] = SDL_RELEASED;
+ }
+ if ( modstate & KMOD_NUM ) {
+ kstate[SDLK_NUMLOCK] = SDL_PRESSED;
+ } else {
+ kstate[SDLK_NUMLOCK] = SDL_RELEASED;
+ }
+
+ /* Set the final modifier state */
+ SDL_SetModState(modstate);
+}
+
+void X11_InitOSKeymap(_THIS)
+{
+ X11_InitKeymap();
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11events_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11events_c.h
new file mode 100644
index 0000000..fe26d9c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11events_c.h
@@ -0,0 +1,34 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+
+/* Functions to be exported */
+extern void X11_InitOSKeymap(_THIS);
+extern void X11_PumpEvents(_THIS);
+extern void X11_SetKeyboardState(Display *display, const char *key_vec);
+
+/* Variables to be exported */
+extern int X11_PendingConfigureNotifyWidth;
+extern int X11_PendingConfigureNotifyHeight;
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma.c
new file mode 100644
index 0000000..c6afbda
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma.c
@@ -0,0 +1,142 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL.h"
+#include "SDL_events.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11video.h"
+
+/* From the X server sources... */
+#define MAX_GAMMA 10.0
+#define MIN_GAMMA (1.0/MAX_GAMMA)
+
+static int X11_SetGammaNoLock(_THIS, float red, float green, float blue)
+{
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if (use_vidmode >= 200) {
+ SDL_NAME(XF86VidModeGamma) gamma;
+ Bool succeeded;
+
+ /* Clamp the gamma values */
+ if ( red < MIN_GAMMA ) {
+ gamma.red = MIN_GAMMA;
+ } else
+ if ( red > MAX_GAMMA ) {
+ gamma.red = MAX_GAMMA;
+ } else {
+ gamma.red = red;
+ }
+ if ( green < MIN_GAMMA ) {
+ gamma.green = MIN_GAMMA;
+ } else
+ if ( green > MAX_GAMMA ) {
+ gamma.green = MAX_GAMMA;
+ } else {
+ gamma.green = green;
+ }
+ if ( blue < MIN_GAMMA ) {
+ gamma.blue = MIN_GAMMA;
+ } else
+ if ( blue > MAX_GAMMA ) {
+ gamma.blue = MAX_GAMMA;
+ } else {
+ gamma.blue = blue;
+ }
+ if ( SDL_GetAppState() & SDL_APPACTIVE ) {
+ succeeded = SDL_NAME(XF86VidModeSetGamma)(SDL_Display, SDL_Screen, &gamma);
+ XSync(SDL_Display, False);
+ } else {
+ gamma_saved[0] = gamma.red;
+ gamma_saved[1] = gamma.green;
+ gamma_saved[2] = gamma.blue;
+ succeeded = True;
+ }
+ if ( succeeded ) {
+ ++gamma_changed;
+ }
+ return succeeded ? 0 : -1;
+ }
+#endif
+ SDL_SetError("Gamma correction not supported");
+ return -1;
+}
+int X11_SetVidModeGamma(_THIS, float red, float green, float blue)
+{
+ int result;
+
+ SDL_Lock_EventThread();
+ result = X11_SetGammaNoLock(this, red, green, blue);
+ SDL_Unlock_EventThread();
+
+ return(result);
+}
+
+static int X11_GetGammaNoLock(_THIS, float *red, float *green, float *blue)
+{
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if (use_vidmode >= 200) {
+ SDL_NAME(XF86VidModeGamma) gamma;
+ if (SDL_NAME(XF86VidModeGetGamma)(SDL_Display, SDL_Screen, &gamma)) {
+ *red = gamma.red;
+ *green = gamma.green;
+ *blue = gamma.blue;
+ return 0;
+ }
+ return -1;
+ }
+#endif
+ return -1;
+}
+int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue)
+{
+ int result;
+
+ SDL_Lock_EventThread();
+ result = X11_GetGammaNoLock(this, red, green, blue);
+ SDL_Unlock_EventThread();
+
+ return(result);
+}
+
+void X11_SaveVidModeGamma(_THIS)
+{
+ /* Try to save the current gamma, otherwise disable gamma control */
+ if ( X11_GetGammaNoLock(this,
+ &gamma_saved[0], &gamma_saved[1], &gamma_saved[2]) < 0 ) {
+ this->SetGamma = 0;
+ this->GetGamma = 0;
+ }
+ gamma_changed = 0;
+}
+void X11_SwapVidModeGamma(_THIS)
+{
+ float new_gamma[3];
+
+ if ( gamma_changed ) {
+ new_gamma[0] = gamma_saved[0];
+ new_gamma[1] = gamma_saved[1];
+ new_gamma[2] = gamma_saved[2];
+ X11_GetGammaNoLock(this, &gamma_saved[0], &gamma_saved[1], &gamma_saved[2]);
+ X11_SetGammaNoLock(this, new_gamma[0], new_gamma[1], new_gamma[2]);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma_c.h
new file mode 100644
index 0000000..c46350f
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gamma_c.h
@@ -0,0 +1,32 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_x11gamma_h
+#define _SDL_x11gamma_h
+
+extern int X11_SetVidModeGamma(_THIS, float red, float green, float blue);
+extern int X11_GetVidModeGamma(_THIS, float *red, float *green, float *blue);
+extern void X11_SaveVidModeGamma(_THIS);
+extern void X11_SwapVidModeGamma(_THIS);
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl.c
new file mode 100644
index 0000000..aa5297b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl.c
@@ -0,0 +1,577 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11dga_c.h"
+#include "SDL_x11gl_c.h"
+
+#if defined(__IRIX__)
+/* IRIX doesn't have a GL library versioning system */
+#define DEFAULT_OPENGL "libGL.so"
+#elif defined(__MACOSX__)
+#define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib"
+#elif defined(__QNXNTO__)
+#define DEFAULT_OPENGL "libGL.so.3"
+#elif defined(__OpenBSD__)
+#define DEFAULT_OPENGL "libGL.so.4.0"
+#else
+#define DEFAULT_OPENGL "libGL.so.1"
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+#endif
+
+/* GLX_EXT_visual_rating stuff that might not be in the system headers... */
+#ifndef GLX_VISUAL_CAVEAT_EXT
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#endif
+#ifndef GLX_NONE_EXT
+#define GLX_NONE_EXT 0x8000
+#endif
+#ifndef GLX_SLOW_VISUAL_EXT
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#endif
+#ifndef GLX_NON_CONFORMANT_VISUAL_EXT
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+#endif
+
+
+#if SDL_VIDEO_OPENGL_GLX
+static int glXExtensionSupported(_THIS, const char *extension)
+{
+ const char *extensions;
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if ( where || *extension == '\0' ) {
+ return 0;
+ }
+
+ extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen);
+ /* It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings, etc.
+ */
+
+ /* http://bugs.debian.org/537487 */
+ if (extensions == NULL) {
+ return 0;
+ }
+
+ start = extensions;
+
+ for (;;) {
+ where = SDL_strstr(start, extension);
+ if (!where) break;
+
+ terminator = where + strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0') return 1;
+
+ start = terminator;
+ }
+ return 0;
+}
+#endif /* SDL_VIDEO_OPENGL_GLX */
+
+XVisualInfo *X11_GL_GetVisual(_THIS)
+{
+#if SDL_VIDEO_OPENGL_GLX
+ /* 64 seems nice. */
+ int attribs[64];
+ int i;
+
+ /* load the gl driver from a default path */
+ if ( ! this->gl_config.driver_loaded ) {
+ /* no driver has been loaded, use default (ourselves) */
+ if ( X11_GL_LoadLibrary(this, NULL) < 0 ) {
+ return NULL;
+ }
+ }
+
+ /* See if we already have a window which we must use */
+ if ( SDL_windowid ) {
+ XWindowAttributes a;
+ XVisualInfo vi_in;
+ int out_count;
+
+ XGetWindowAttributes(SDL_Display, SDL_Window, &a);
+ vi_in.screen = SDL_Screen;
+ vi_in.visualid = XVisualIDFromVisual(a.visual);
+ glx_visualinfo = XGetVisualInfo(SDL_Display,
+ VisualScreenMask|VisualIDMask, &vi_in, &out_count);
+ return glx_visualinfo;
+ }
+
+ /* Setup our GLX attributes according to the gl_config. */
+ i = 0;
+ attribs[i++] = GLX_RGBA;
+ attribs[i++] = GLX_RED_SIZE;
+ attribs[i++] = this->gl_config.red_size;
+ attribs[i++] = GLX_GREEN_SIZE;
+ attribs[i++] = this->gl_config.green_size;
+ attribs[i++] = GLX_BLUE_SIZE;
+ attribs[i++] = this->gl_config.blue_size;
+
+ if( this->gl_config.alpha_size ) {
+ attribs[i++] = GLX_ALPHA_SIZE;
+ attribs[i++] = this->gl_config.alpha_size;
+ }
+
+ if( this->gl_config.double_buffer ) {
+ attribs[i++] = GLX_DOUBLEBUFFER;
+ }
+
+ attribs[i++] = GLX_DEPTH_SIZE;
+ attribs[i++] = this->gl_config.depth_size;
+
+ if( this->gl_config.stencil_size ) {
+ attribs[i++] = GLX_STENCIL_SIZE;
+ attribs[i++] = this->gl_config.stencil_size;
+ }
+
+ if( this->gl_config.accum_red_size ) {
+ attribs[i++] = GLX_ACCUM_RED_SIZE;
+ attribs[i++] = this->gl_config.accum_red_size;
+ }
+
+ if( this->gl_config.accum_green_size ) {
+ attribs[i++] = GLX_ACCUM_GREEN_SIZE;
+ attribs[i++] = this->gl_config.accum_green_size;
+ }
+
+ if( this->gl_config.accum_blue_size ) {
+ attribs[i++] = GLX_ACCUM_BLUE_SIZE;
+ attribs[i++] = this->gl_config.accum_blue_size;
+ }
+
+ if( this->gl_config.accum_alpha_size ) {
+ attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
+ attribs[i++] = this->gl_config.accum_alpha_size;
+ }
+
+ if( this->gl_config.stereo ) {
+ attribs[i++] = GLX_STEREO;
+ }
+
+ if( this->gl_config.multisamplebuffers ) {
+ attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
+ attribs[i++] = this->gl_config.multisamplebuffers;
+ }
+
+ if( this->gl_config.multisamplesamples ) {
+ attribs[i++] = GLX_SAMPLES_ARB;
+ attribs[i++] = this->gl_config.multisamplesamples;
+ }
+
+ if( this->gl_config.accelerated >= 0 &&
+ glXExtensionSupported(this, "GLX_EXT_visual_rating") ) {
+ attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
+ attribs[i++] = GLX_NONE_EXT;
+ }
+
+#ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */
+ if ( !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) {
+ attribs[i++] = GLX_X_VISUAL_TYPE;
+ attribs[i++] = GLX_DIRECT_COLOR;
+ }
+#endif
+ attribs[i++] = None;
+
+ glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display,
+ SDL_Screen, attribs);
+#ifdef GLX_DIRECT_COLOR
+ if( !glx_visualinfo && !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { /* No DirectColor visual? Try again.. */
+ attribs[i-3] = None;
+ glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display,
+ SDL_Screen, attribs);
+ }
+#endif
+ if( !glx_visualinfo ) {
+ SDL_SetError( "Couldn't find matching GLX visual");
+ return NULL;
+ }
+/*
+ printf("Found GLX visual 0x%x\n", glx_visualinfo->visualid);
+*/
+ return glx_visualinfo;
+#else
+ SDL_SetError("X11 driver not configured with OpenGL");
+ return NULL;
+#endif
+}
+
+int X11_GL_CreateWindow(_THIS, int w, int h)
+{
+ int retval;
+#if SDL_VIDEO_OPENGL_GLX
+ XSetWindowAttributes attributes;
+ unsigned long mask;
+ unsigned long black;
+
+ black = (glx_visualinfo->visual == DefaultVisual(SDL_Display,
+ SDL_Screen))
+ ? BlackPixel(SDL_Display, SDL_Screen) : 0;
+ attributes.background_pixel = black;
+ attributes.border_pixel = black;
+ attributes.colormap = SDL_XColorMap;
+ mask = CWBackPixel | CWBorderPixel | CWColormap;
+
+ SDL_Window = XCreateWindow(SDL_Display, WMwindow,
+ 0, 0, w, h, 0, glx_visualinfo->depth,
+ InputOutput, glx_visualinfo->visual,
+ mask, &attributes);
+ if ( !SDL_Window ) {
+ SDL_SetError("Could not create window");
+ return -1;
+ }
+ retval = 0;
+#else
+ SDL_SetError("X11 driver not configured with OpenGL");
+ retval = -1;
+#endif
+ return(retval);
+}
+
+int X11_GL_CreateContext(_THIS)
+{
+ int retval;
+#if SDL_VIDEO_OPENGL_GLX
+
+ /* We do this to create a clean separation between X and GLX errors. */
+ XSync( SDL_Display, False );
+ glx_context = this->gl_data->glXCreateContext(GFX_Display,
+ glx_visualinfo, NULL, True);
+ XSync( GFX_Display, False );
+
+ if ( glx_context == NULL ) {
+ SDL_SetError("Could not create GL context");
+ return(-1);
+ }
+ if ( X11_GL_MakeCurrent(this) < 0 ) {
+ return(-1);
+ }
+ gl_active = 1;
+
+ if ( !glXExtensionSupported(this, "GLX_SGI_swap_control") ) {
+ this->gl_data->glXSwapIntervalSGI = NULL;
+ }
+ if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) {
+ this->gl_data->glXSwapIntervalMESA = NULL;
+ }
+ if ( !glXExtensionSupported(this, "GLX_EXT_swap_control") ) {
+ this->gl_data->glXSwapIntervalEXT = NULL;
+ }
+
+ if ( this->gl_config.swap_control >= 0 ) {
+ int rc = -1;
+ if ( this->gl_data->glXSwapIntervalEXT ) {
+ rc = this->gl_data->glXSwapIntervalEXT(GFX_Display, SDL_Window,
+ this->gl_config.swap_control);
+ } else if ( this->gl_data->glXSwapIntervalMESA ) {
+ rc = this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control);
+ } else if ( this->gl_data->glXSwapIntervalSGI ) {
+ rc = this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control);
+ }
+ if (rc == 0) {
+ this->gl_data->swap_interval = this->gl_config.swap_control;
+ }
+ }
+#else
+ SDL_SetError("X11 driver not configured with OpenGL");
+#endif
+ if ( gl_active ) {
+ retval = 0;
+ } else {
+ retval = -1;
+ }
+ return(retval);
+}
+
+void X11_GL_Shutdown(_THIS)
+{
+#if SDL_VIDEO_OPENGL_GLX
+ /* Clean up OpenGL */
+ if( glx_context ) {
+ this->gl_data->glXMakeCurrent(GFX_Display, None, NULL);
+
+ if (glx_context != NULL)
+ this->gl_data->glXDestroyContext(GFX_Display, glx_context);
+
+ glx_context = NULL;
+ }
+ gl_active = 0;
+#endif /* SDL_VIDEO_OPENGL_GLX */
+}
+
+#if SDL_VIDEO_OPENGL_GLX
+
+/* Make the current context active */
+int X11_GL_MakeCurrent(_THIS)
+{
+ int retval;
+
+ retval = 0;
+ if ( ! this->gl_data->glXMakeCurrent(GFX_Display,
+ SDL_Window, glx_context) ) {
+ SDL_SetError("Unable to make GL context current");
+ retval = -1;
+ }
+ XSync( GFX_Display, False );
+
+ /* More Voodoo X server workarounds... Grr... */
+ SDL_Lock_EventThread();
+ X11_CheckDGAMouse(this);
+ SDL_Unlock_EventThread();
+
+ return(retval);
+}
+
+/* Get attribute data from glX. */
+int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+ int retval = -1;
+ int unsupported = 0;
+ int glx_attrib = None;
+
+ switch( attrib ) {
+ case SDL_GL_RED_SIZE:
+ glx_attrib = GLX_RED_SIZE;
+ break;
+ case SDL_GL_GREEN_SIZE:
+ glx_attrib = GLX_GREEN_SIZE;
+ break;
+ case SDL_GL_BLUE_SIZE:
+ glx_attrib = GLX_BLUE_SIZE;
+ break;
+ case SDL_GL_ALPHA_SIZE:
+ glx_attrib = GLX_ALPHA_SIZE;
+ break;
+ case SDL_GL_DOUBLEBUFFER:
+ glx_attrib = GLX_DOUBLEBUFFER;
+ break;
+ case SDL_GL_BUFFER_SIZE:
+ glx_attrib = GLX_BUFFER_SIZE;
+ break;
+ case SDL_GL_DEPTH_SIZE:
+ glx_attrib = GLX_DEPTH_SIZE;
+ break;
+ case SDL_GL_STENCIL_SIZE:
+ glx_attrib = GLX_STENCIL_SIZE;
+ break;
+ case SDL_GL_ACCUM_RED_SIZE:
+ glx_attrib = GLX_ACCUM_RED_SIZE;
+ break;
+ case SDL_GL_ACCUM_GREEN_SIZE:
+ glx_attrib = GLX_ACCUM_GREEN_SIZE;
+ break;
+ case SDL_GL_ACCUM_BLUE_SIZE:
+ glx_attrib = GLX_ACCUM_BLUE_SIZE;
+ break;
+ case SDL_GL_ACCUM_ALPHA_SIZE:
+ glx_attrib = GLX_ACCUM_ALPHA_SIZE;
+ break;
+ case SDL_GL_STEREO:
+ glx_attrib = GLX_STEREO;
+ break;
+ case SDL_GL_MULTISAMPLEBUFFERS:
+ glx_attrib = GLX_SAMPLE_BUFFERS_ARB;
+ break;
+ case SDL_GL_MULTISAMPLESAMPLES:
+ glx_attrib = GLX_SAMPLES_ARB;
+ break;
+ case SDL_GL_ACCELERATED_VISUAL:
+ if ( glXExtensionSupported(this, "GLX_EXT_visual_rating") ) {
+ glx_attrib = GLX_VISUAL_CAVEAT_EXT;
+ retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value);
+ if ( *value == GLX_SLOW_VISUAL_EXT ) {
+ *value = SDL_FALSE;
+ } else {
+ *value = SDL_TRUE;
+ }
+ return retval;
+ } else {
+ unsupported = 1;
+ }
+ break;
+ case SDL_GL_SWAP_CONTROL:
+ if ( ( this->gl_data->glXSwapIntervalEXT ) ||
+ ( this->gl_data->glXSwapIntervalMESA ) ||
+ ( this->gl_data->glXSwapIntervalSGI ) ) {
+ *value = this->gl_data->swap_interval;
+ return 0;
+ } else {
+ unsupported = 1;
+ }
+ break;
+ default:
+ unsupported = 1;
+ break;
+ }
+
+ if (unsupported) {
+ SDL_SetError("OpenGL attribute is unsupported on this system");
+ } else {
+ retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value);
+ }
+ return retval;
+}
+
+void X11_GL_SwapBuffers(_THIS)
+{
+ this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window);
+}
+
+#endif /* SDL_VIDEO_OPENGL_GLX */
+
+#define OPENGL_REQUIRS_DLOPEN
+#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
+#include <dlfcn.h>
+#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
+#define GL_LoadFunction dlsym
+#define GL_UnloadObject dlclose
+#else
+#define GL_LoadObject SDL_LoadObject
+#define GL_LoadFunction SDL_LoadFunction
+#define GL_UnloadObject SDL_UnloadObject
+#endif
+
+void X11_GL_UnloadLibrary(_THIS)
+{
+#if SDL_VIDEO_OPENGL_GLX
+ if ( this->gl_config.driver_loaded ) {
+
+ GL_UnloadObject(this->gl_config.dll_handle);
+
+ this->gl_data->glXGetProcAddress = NULL;
+ this->gl_data->glXChooseVisual = NULL;
+ this->gl_data->glXCreateContext = NULL;
+ this->gl_data->glXDestroyContext = NULL;
+ this->gl_data->glXMakeCurrent = NULL;
+ this->gl_data->glXSwapBuffers = NULL;
+ this->gl_data->glXSwapIntervalSGI = NULL;
+ this->gl_data->glXSwapIntervalMESA = NULL;
+ this->gl_data->glXSwapIntervalEXT = NULL;
+
+ this->gl_config.dll_handle = NULL;
+ this->gl_config.driver_loaded = 0;
+ }
+#endif
+}
+
+#if SDL_VIDEO_OPENGL_GLX
+
+/* Passing a NULL path means load pointers from the application */
+int X11_GL_LoadLibrary(_THIS, const char* path)
+{
+ void* handle = NULL;
+
+ if ( gl_active ) {
+ SDL_SetError("OpenGL context already created");
+ return -1;
+ }
+
+ if ( path == NULL ) {
+ path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
+ if ( path == NULL ) {
+ path = DEFAULT_OPENGL;
+ }
+ }
+
+ handle = GL_LoadObject(path);
+ if ( handle == NULL ) {
+#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
+ SDL_SetError("Failed loading %s", path);
+#else
+ /* SDL_LoadObject() will call SDL_SetError() for us. */
+#endif
+ return -1;
+ }
+
+ /* Unload the old driver and reset the pointers */
+ X11_GL_UnloadLibrary(this);
+
+ /* Save the handle for X11_GL_GetProcAddress() */
+ this->gl_config.dll_handle = handle;
+
+ /* Load new function pointers */
+ this->gl_data->glXGetProcAddress =
+ (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB");
+ this->gl_data->glXChooseVisual =
+ (XVisualInfo *(*)(Display *, int, int *)) X11_GL_GetProcAddress(this, "glXChooseVisual");
+ this->gl_data->glXCreateContext =
+ (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(this, "glXCreateContext");
+ this->gl_data->glXDestroyContext =
+ (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(this, "glXDestroyContext");
+ this->gl_data->glXMakeCurrent =
+ (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(this, "glXMakeCurrent");
+ this->gl_data->glXSwapBuffers =
+ (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(this, "glXSwapBuffers");
+ this->gl_data->glXGetConfig =
+ (int (*)(Display *, XVisualInfo *, int, int *)) X11_GL_GetProcAddress(this, "glXGetConfig");
+ this->gl_data->glXQueryExtensionsString =
+ (const char *(*)(Display *, int)) X11_GL_GetProcAddress(this, "glXQueryExtensionsString");
+ this->gl_data->glXSwapIntervalSGI =
+ (int (*)(int)) X11_GL_GetProcAddress(this, "glXSwapIntervalSGI");
+ this->gl_data->glXSwapIntervalMESA =
+ (GLint (*)(unsigned)) X11_GL_GetProcAddress(this, "glXSwapIntervalMESA");
+ this->gl_data->glXSwapIntervalEXT =
+ (int (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(this, "glXSwapIntervalEXT");
+
+ if ( (this->gl_data->glXChooseVisual == NULL) ||
+ (this->gl_data->glXCreateContext == NULL) ||
+ (this->gl_data->glXDestroyContext == NULL) ||
+ (this->gl_data->glXMakeCurrent == NULL) ||
+ (this->gl_data->glXSwapBuffers == NULL) ||
+ (this->gl_data->glXGetConfig == NULL) ||
+ (this->gl_data->glXQueryExtensionsString == NULL)) {
+ GL_UnloadObject(this->gl_config.dll_handle);
+ this->gl_config.dll_handle = NULL;
+ SDL_SetError("Could not retrieve OpenGL functions");
+ return -1;
+ }
+
+ this->gl_config.driver_loaded = 1;
+ if ( path ) {
+ SDL_strlcpy(this->gl_config.driver_path, path,
+ SDL_arraysize(this->gl_config.driver_path));
+ } else {
+ *this->gl_config.driver_path = '\0';
+ }
+ return 0;
+}
+
+void *X11_GL_GetProcAddress(_THIS, const char* proc)
+{
+ if ( this->gl_data->glXGetProcAddress ) {
+ return this->gl_data->glXGetProcAddress((const GLubyte *)proc);
+ }
+ return GL_LoadFunction(this->gl_config.dll_handle, proc);
+}
+
+#endif /* SDL_VIDEO_OPENGL_GLX */
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl_c.h
new file mode 100644
index 0000000..b4822cb
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11gl_c.h
@@ -0,0 +1,99 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#if SDL_VIDEO_OPENGL_GLX
+#include <GL/glx.h>
+#include "SDL_loadso.h"
+#endif
+
+#include "../SDL_sysvideo.h"
+
+struct SDL_PrivateGLData {
+ int gl_active; /* to stop switching drivers while we have a valid context */
+
+#if SDL_VIDEO_OPENGL_GLX
+ GLXContext glx_context; /* Current GL context */
+ XVisualInfo* glx_visualinfo; /* XVisualInfo* returned by glXChooseVisual */
+
+ void * (*glXGetProcAddress)(const GLubyte *procName);
+
+ XVisualInfo* (*glXChooseVisual)
+ ( Display* dpy,
+ int screen,
+ int* attribList );
+
+ GLXContext (*glXCreateContext)
+ ( Display* dpy,
+ XVisualInfo* vis,
+ GLXContext shareList,
+ Bool direct );
+
+ void (*glXDestroyContext)
+ ( Display* dpy,
+ GLXContext ctx );
+
+ Bool (*glXMakeCurrent)
+ ( Display* dpy,
+ GLXDrawable drawable,
+ GLXContext ctx );
+
+ void (*glXSwapBuffers)
+ ( Display* dpy,
+ GLXDrawable drawable );
+
+ int (*glXGetConfig)
+ ( Display* dpy,
+ XVisualInfo* visual_info,
+ int attrib,
+ int* value );
+
+ const char *(*glXQueryExtensionsString)
+ ( Display* dpy,
+ int screen );
+
+ int (*glXSwapIntervalSGI) ( int interval );
+ GLint (*glXSwapIntervalMESA) ( unsigned interval );
+ int (*glXSwapIntervalEXT)( Display *dpy, GLXDrawable drw, int interval);
+ int swap_interval;
+#endif /* SDL_VIDEO_OPENGL_GLX */
+};
+
+/* Old variable names */
+#define gl_active (this->gl_data->gl_active)
+#define glx_context (this->gl_data->glx_context)
+#define glx_visualinfo (this->gl_data->glx_visualinfo)
+
+/* OpenGL functions */
+extern XVisualInfo *X11_GL_GetVisual(_THIS);
+extern int X11_GL_CreateWindow(_THIS, int w, int h);
+extern int X11_GL_CreateContext(_THIS);
+extern void X11_GL_Shutdown(_THIS);
+#if SDL_VIDEO_OPENGL_GLX
+extern int X11_GL_MakeCurrent(_THIS);
+extern int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+extern void X11_GL_SwapBuffers(_THIS);
+extern int X11_GL_LoadLibrary(_THIS, const char* path);
+extern void *X11_GL_GetProcAddress(_THIS, const char* proc);
+#endif
+extern void X11_GL_UnloadLibrary(_THIS);
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11image.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11image.c
new file mode 100644
index 0000000..464bc37
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11image.c
@@ -0,0 +1,316 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "SDL_endian.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11image_c.h"
+
+#ifndef NO_SHARED_MEMORY
+
+/* Shared memory error handler routine */
+static int shm_error;
+static int (*X_handler)(Display *, XErrorEvent *) = NULL;
+static int shm_errhandler(Display *d, XErrorEvent *e)
+{
+ if ( e->error_code == BadAccess ) {
+ shm_error = True;
+ return(0);
+ } else
+ return(X_handler(d,e));
+}
+
+static void try_mitshm(_THIS, SDL_Surface *screen)
+{
+ /* Dynamic X11 may not have SHM entry points on this box. */
+ if ((use_mitshm) && (!SDL_X11_HAVE_SHM))
+ use_mitshm = 0;
+
+ if(!use_mitshm)
+ return;
+ shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch,
+ IPC_CREAT | 0777);
+ if ( shminfo.shmid >= 0 ) {
+ shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
+ shminfo.readOnly = False;
+ if ( shminfo.shmaddr != (char *)-1 ) {
+ shm_error = False;
+ X_handler = XSetErrorHandler(shm_errhandler);
+ XShmAttach(SDL_Display, &shminfo);
+ XSync(SDL_Display, True);
+ XSetErrorHandler(X_handler);
+ if ( shm_error )
+ shmdt(shminfo.shmaddr);
+ } else {
+ shm_error = True;
+ }
+ shmctl(shminfo.shmid, IPC_RMID, NULL);
+ } else {
+ shm_error = True;
+ }
+ if ( shm_error )
+ use_mitshm = 0;
+ if ( use_mitshm )
+ screen->pixels = shminfo.shmaddr;
+}
+#endif /* ! NO_SHARED_MEMORY */
+
+/* Various screen update functions available */
+static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects);
+
+int X11_SetupImage(_THIS, SDL_Surface *screen)
+{
+#ifndef NO_SHARED_MEMORY
+ try_mitshm(this, screen);
+ if(use_mitshm) {
+ SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual,
+ this->hidden->depth, ZPixmap,
+ shminfo.shmaddr, &shminfo,
+ screen->w, screen->h);
+ if(!SDL_Ximage) {
+ XShmDetach(SDL_Display, &shminfo);
+ XSync(SDL_Display, False);
+ shmdt(shminfo.shmaddr);
+ screen->pixels = NULL;
+ goto error;
+ }
+ this->UpdateRects = X11_MITSHMUpdate;
+ }
+ if(!use_mitshm)
+#endif /* not NO_SHARED_MEMORY */
+ {
+ screen->pixels = SDL_malloc(screen->h*screen->pitch);
+ if ( screen->pixels == NULL ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
+ this->hidden->depth, ZPixmap, 0,
+ (char *)screen->pixels,
+ screen->w, screen->h,
+ 32, 0);
+ if ( SDL_Ximage == NULL )
+ goto error;
+ /* XPutImage will convert byte sex automatically */
+ SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+ ? MSBFirst : LSBFirst;
+ this->UpdateRects = X11_NormalUpdate;
+ }
+ screen->pitch = SDL_Ximage->bytes_per_line;
+ return(0);
+
+error:
+ SDL_SetError("Couldn't create XImage");
+ return 1;
+}
+
+void X11_DestroyImage(_THIS, SDL_Surface *screen)
+{
+ if ( SDL_Ximage ) {
+ XDestroyImage(SDL_Ximage);
+#ifndef NO_SHARED_MEMORY
+ if ( use_mitshm ) {
+ XShmDetach(SDL_Display, &shminfo);
+ XSync(SDL_Display, False);
+ shmdt(shminfo.shmaddr);
+ }
+#endif /* ! NO_SHARED_MEMORY */
+ SDL_Ximage = NULL;
+ }
+ if ( screen ) {
+ screen->pixels = NULL;
+ }
+}
+
+/* Determine the number of CPUs in the system */
+static int num_CPU(void)
+{
+ static int num_cpus = 0;
+
+ if(!num_cpus) {
+#if defined(__LINUX__)
+ char line[BUFSIZ];
+ FILE *pstat = fopen("/proc/stat", "r");
+ if ( pstat ) {
+ while ( fgets(line, sizeof(line), pstat) ) {
+ if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') {
+ ++num_cpus;
+ }
+ }
+ fclose(pstat);
+ }
+#elif defined(__IRIX__)
+ num_cpus = sysconf(_SC_NPROC_ONLN);
+#elif defined(_SC_NPROCESSORS_ONLN)
+ /* number of processors online (SVR4.0MP compliant machines) */
+ num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+#elif defined(_SC_NPROCESSORS_CONF)
+ /* number of processors configured (SVR4.0MP compliant machines) */
+ num_cpus = sysconf(_SC_NPROCESSORS_CONF);
+#endif
+ if ( num_cpus <= 0 ) {
+ num_cpus = 1;
+ }
+ }
+ return num_cpus;
+}
+
+int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
+{
+ int retval;
+
+ X11_DestroyImage(this, screen);
+ if ( flags & SDL_OPENGL ) { /* No image when using GL */
+ retval = 0;
+ } else {
+ retval = X11_SetupImage(this, screen);
+ /* We support asynchronous blitting on the display */
+ if ( flags & SDL_ASYNCBLIT ) {
+ /* This is actually slower on single-CPU systems,
+ probably because of CPU contention between the
+ X server and the application.
+ Note: Is this still true with XFree86 4.0?
+ */
+ if ( num_CPU() > 1 ) {
+ screen->flags |= SDL_ASYNCBLIT;
+ }
+ }
+ }
+ return(retval);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+int X11_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+void X11_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+int X11_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ if ( (surface == SDL_VideoSurface) && blit_queued ) {
+ XSync(GFX_Display, False);
+ blit_queued = 0;
+ }
+ return(0);
+}
+void X11_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+int X11_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+ int i;
+
+ for (i = 0; i < numrects; ++i) {
+ if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
+ continue;
+ }
+ XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
+ rects[i].x, rects[i].y,
+ rects[i].x, rects[i].y, rects[i].w, rects[i].h);
+ }
+ if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
+ XFlush(GFX_Display);
+ blit_queued = 1;
+ } else {
+ XSync(GFX_Display, False);
+ }
+}
+
+static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+#ifndef NO_SHARED_MEMORY
+ int i;
+
+ for ( i=0; i<numrects; ++i ) {
+ if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */
+ continue;
+ }
+ XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage,
+ rects[i].x, rects[i].y,
+ rects[i].x, rects[i].y, rects[i].w, rects[i].h,
+ False);
+ }
+ if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) {
+ XFlush(GFX_Display);
+ blit_queued = 1;
+ } else {
+ XSync(GFX_Display, False);
+ }
+#endif /* ! NO_SHARED_MEMORY */
+}
+
+/* There's a problem with the automatic refreshing of the display.
+ Even though the XVideo code uses the GFX_Display to update the
+ video memory, it appears that updating the window asynchronously
+ from a different thread will cause "blackouts" of the window.
+ This is a sort of a hacked workaround for the problem.
+*/
+static int enable_autorefresh = 1;
+
+void X11_DisableAutoRefresh(_THIS)
+{
+ --enable_autorefresh;
+}
+
+void X11_EnableAutoRefresh(_THIS)
+{
+ ++enable_autorefresh;
+}
+
+void X11_RefreshDisplay(_THIS)
+{
+ /* Don't refresh a display that doesn't have an image (like GL)
+ Instead, post an expose event so the application can refresh.
+ */
+ if ( ! SDL_Ximage || (enable_autorefresh <= 0) ) {
+ SDL_PrivateExpose();
+ return;
+ }
+#ifndef NO_SHARED_MEMORY
+ if ( this->UpdateRects == X11_MITSHMUpdate ) {
+ XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
+ 0, 0, 0, 0, this->screen->w, this->screen->h,
+ False);
+ } else
+#endif /* ! NO_SHARED_MEMORY */
+ {
+ XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage,
+ 0, 0, 0, 0, this->screen->w, this->screen->h);
+ }
+ XSync(SDL_Display, False);
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11image_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11image_c.h
new file mode 100644
index 0000000..2de1571
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11image_c.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+
+extern int X11_SetupImage(_THIS, SDL_Surface *screen);
+extern void X11_DestroyImage(_THIS, SDL_Surface *screen);
+extern int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags);
+
+extern int X11_AllocHWSurface(_THIS, SDL_Surface *surface);
+extern void X11_FreeHWSurface(_THIS, SDL_Surface *surface);
+extern int X11_LockHWSurface(_THIS, SDL_Surface *surface);
+extern void X11_UnlockHWSurface(_THIS, SDL_Surface *surface);
+extern int X11_FlipHWSurface(_THIS, SDL_Surface *surface);
+
+extern void X11_DisableAutoRefresh(_THIS);
+extern void X11_EnableAutoRefresh(_THIS);
+extern void X11_RefreshDisplay(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes.c
new file mode 100644
index 0000000..c232e6a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes.c
@@ -0,0 +1,1143 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Utilities for getting and setting the X display mode */
+
+#include <stdio.h>
+
+#include "SDL_timer.h"
+#include "SDL_events.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11video.h"
+#include "SDL_x11wm_c.h"
+#include "SDL_x11modes_c.h"
+#include "SDL_x11image_c.h"
+
+/*#define X11MODES_DEBUG*/
+
+#define MAX(a, b) (a > b ? a : b)
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+static int cmpmodelist(const void *va, const void *vb)
+{
+ const SDL_Rect *a = *(const SDL_Rect **)va;
+ const SDL_Rect *b = *(const SDL_Rect **)vb;
+ if ( a->w == b->w )
+ return b->h - a->h;
+ else
+ return b->w - a->w;
+}
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
+{
+ Bool retval;
+ int dotclock;
+ SDL_NAME(XF86VidModeModeLine) l;
+ SDL_memset(&l, 0, sizeof(l));
+ retval = SDL_NAME(XF86VidModeGetModeLine)(dpy, scr, &dotclock, &l);
+ info->dotclock = dotclock;
+ info->hdisplay = l.hdisplay;
+ info->hsyncstart = l.hsyncstart;
+ info->hsyncend = l.hsyncend;
+ info->htotal = l.htotal;
+ info->hskew = l.hskew;
+ info->vdisplay = l.vdisplay;
+ info->vsyncstart = l.vsyncstart;
+ info->vsyncend = l.vsyncend;
+ info->vtotal = l.vtotal;
+ info->flags = l.flags;
+ info->privsize = l.privsize;
+ info->private = l.private;
+ return retval;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+static void save_mode(_THIS)
+{
+ SDL_memset(&saved_mode, 0, sizeof(saved_mode));
+ SDL_NAME(XF86VidModeGetModeInfo)(SDL_Display,SDL_Screen,&saved_mode);
+ SDL_NAME(XF86VidModeGetViewPort)(SDL_Display,SDL_Screen,&saved_view.x,&saved_view.y);
+}
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+static void restore_mode(_THIS)
+{
+ SDL_NAME(XF86VidModeModeLine) mode;
+ int unused;
+
+ if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
+ if ( (saved_mode.hdisplay != mode.hdisplay) ||
+ (saved_mode.vdisplay != mode.vdisplay) ) {
+ SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, &saved_mode);
+ }
+ }
+ if ( (saved_view.x != 0) || (saved_view.y != 0) ) {
+ SDL_NAME(XF86VidModeSetViewPort)(SDL_Display, SDL_Screen, saved_view.x, saved_view.y);
+ }
+}
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+static int cmpmodes(const void *va, const void *vb)
+{
+ const SDL_NAME(XF86VidModeModeInfo) *a = *(const SDL_NAME(XF86VidModeModeInfo)**)va;
+ const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb;
+ if ( a->hdisplay == b->hdisplay )
+ return b->vdisplay - a->vdisplay;
+ else
+ return b->hdisplay - a->hdisplay;
+}
+#endif
+
+static void get_real_resolution(_THIS, int* w, int* h);
+
+static void set_best_resolution(_THIS, int width, int height)
+{
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if ( use_vidmode ) {
+ SDL_NAME(XF86VidModeModeLine) mode;
+ SDL_NAME(XF86VidModeModeInfo) **modes;
+ int i;
+ int nmodes;
+ int best = -1;
+
+ if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
+ SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) {
+ for ( i = 0; i < nmodes ; i++ ) {
+ if ( (modes[i]->hdisplay == width) &&
+ (modes[i]->vdisplay == height) ) {
+ best = i;
+ break;
+ }
+ if ( modes[i]->hdisplay >= width &&
+ modes[i]->vdisplay >= height ) {
+ if ( best < 0 ||
+ (modes[i]->hdisplay < modes[best]->hdisplay &&
+ modes[i]->vdisplay <= modes[best]->vdisplay) ||
+ (modes[i]->vdisplay < modes[best]->vdisplay &&
+ modes[i]->hdisplay <= modes[best]->hdisplay) ) {
+ best = i;
+ }
+ }
+ }
+ if ( best >= 0 &&
+ ((modes[best]->hdisplay != mode.hdisplay) ||
+ (modes[best]->vdisplay != mode.vdisplay)) ) {
+#ifdef X11MODES_DEBUG
+ printf("Best Mode %d: %d x %d @ %d\n", best,
+ modes[best]->hdisplay, modes[best]->vdisplay,
+ (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 );
+#endif
+ SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]);
+ }
+ XFree(modes);
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+ /* XiG */
+#if SDL_VIDEO_DRIVER_X11_XME
+ if ( use_xme && SDL_modelist ) {
+ int i;
+
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
+ width, height);
+#endif
+ for ( i=0; SDL_modelist[i]; ++i ) {
+ if ( (SDL_modelist[i]->w >= width) &&
+ (SDL_modelist[i]->h >= height) ) {
+ break;
+ }
+ }
+
+ if ( SDL_modelist[i] ) { /* found one, lets try it */
+ int w, h;
+
+ /* check current mode so we can avoid uneccessary mode changes */
+ get_real_resolution(this, &w, &h);
+
+ if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XME: set_best_resolution: "
+ "XiGMiscChangeResolution: %d %d\n",
+ SDL_modelist[i]->w, SDL_modelist[i]->h);
+#endif
+ XiGMiscChangeResolution(SDL_Display,
+ SDL_Screen,
+ 0, /* view */
+ SDL_modelist[i]->w,
+ SDL_modelist[i]->h,
+ 0);
+ XSync(SDL_Display, False);
+ }
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XME */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ if ( use_xrandr && SDL_modelist ) {
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
+ width, height);
+#endif
+ int i, nsizes;
+ XRRScreenSize *sizes;
+
+ /* find the smallest resolution that is at least as big as the user requested */
+ sizes = XRRConfigSizes(screen_config, &nsizes);
+ for ( i = (nsizes-1); i >= 0; i-- ) {
+ if ( (SDL_modelist[i]->w >= width) &&
+ (SDL_modelist[i]->h >= height) ) {
+ break;
+ }
+ }
+
+ if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */
+ int w, h;
+
+ /* check current mode so we can avoid uneccessary mode changes */
+ get_real_resolution(this, &w, &h);
+
+ if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
+ int size_id;
+
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XRANDR: set_best_resolution: "
+ "XXRSetScreenConfig: %d %d\n",
+ SDL_modelist[i]->w, SDL_modelist[i]->h);
+#endif
+
+ /* find the matching size entry index */
+ for ( size_id = 0; size_id < nsizes; ++size_id ) {
+ if ( (sizes[size_id].width == SDL_modelist[i]->w) &&
+ (sizes[size_id].height == SDL_modelist[i]->h) )
+ break;
+ }
+
+ XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
+ size_id, saved_rotation, CurrentTime);
+ }
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+}
+
+static void get_real_resolution(_THIS, int* w, int* h)
+{
+#if SDL_VIDEO_DRIVER_X11_XME
+ if ( use_xme ) {
+ int ractive;
+ XiGMiscResolutionInfo *modelist;
+
+ XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
+ 0, /* view */
+ &ractive, &modelist);
+ *w = modelist[ractive].width;
+ *h = modelist[ractive].height;
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
+#endif
+ XFree(modelist);
+ return;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XME */
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if ( use_vidmode ) {
+ SDL_NAME(XF86VidModeModeLine) mode;
+ int unused;
+
+ if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
+ *w = mode.hdisplay;
+ *h = mode.vdisplay;
+ return;
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ if ( use_xrandr ) {
+ int nsizes;
+ XRRScreenSize* sizes;
+
+ sizes = XRRConfigSizes(screen_config, &nsizes);
+ if ( nsizes > 0 ) {
+ int cur_size;
+ Rotation cur_rotation;
+
+ cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
+ if ( cur_size >= 0 && cur_size < nsizes ) {
+ *w = sizes[cur_size].width;
+ *h = sizes[cur_size].height;
+ }
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
+#endif
+ return;
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if ( use_xinerama ) {
+ *w = xinerama_info.width;
+ *h = xinerama_info.height;
+ return;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+ *w = DisplayWidth(SDL_Display, SDL_Screen);
+ *h = DisplayHeight(SDL_Display, SDL_Screen);
+}
+
+/* Called after mapping a window - waits until the window is mapped */
+void X11_WaitMapped(_THIS, Window win)
+{
+ XEvent event;
+ do {
+ XMaskEvent(SDL_Display, StructureNotifyMask, &event);
+ } while ( (event.type != MapNotify) || (event.xmap.event != win) );
+}
+
+/* Called after unmapping a window - waits until the window is unmapped */
+void X11_WaitUnmapped(_THIS, Window win)
+{
+ XEvent event;
+ do {
+ XMaskEvent(SDL_Display, StructureNotifyMask, &event);
+ } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) );
+}
+
+static void move_cursor_to(_THIS, int x, int y)
+{
+ XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
+}
+
+static int add_default_visual(_THIS)
+{
+ int i;
+ int n = this->hidden->nvisuals;
+ for (i=0; i<n; i++) {
+ if (this->hidden->visuals[i].visual == DefaultVisual(SDL_Display, SDL_Screen)) return n;
+ }
+ this->hidden->visuals[n].depth = DefaultDepth(SDL_Display, SDL_Screen);;
+ this->hidden->visuals[n].visual = DefaultVisual(SDL_Display, SDL_Screen);;
+ this->hidden->nvisuals++;
+ return(this->hidden->nvisuals);
+}
+static int add_visual(_THIS, int depth, int class)
+{
+ XVisualInfo vi;
+ if(XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) {
+ int n = this->hidden->nvisuals;
+ this->hidden->visuals[n].depth = vi.depth;
+ this->hidden->visuals[n].visual = vi.visual;
+ this->hidden->nvisuals++;
+ }
+ return(this->hidden->nvisuals);
+}
+static int add_visual_byid(_THIS, const char *visual_id)
+{
+ XVisualInfo *vi, template;
+ int nvis;
+
+ if ( visual_id ) {
+ SDL_memset(&template, 0, (sizeof template));
+ template.visualid = SDL_strtol(visual_id, NULL, 0);
+ vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis);
+ if ( vi ) {
+ int n = this->hidden->nvisuals;
+ this->hidden->visuals[n].depth = vi->depth;
+ this->hidden->visuals[n].visual = vi->visual;
+ this->hidden->nvisuals++;
+ XFree(vi);
+ }
+ }
+ return(this->hidden->nvisuals);
+}
+
+/* Global for the error handler */
+int vm_event, vm_error = -1;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+static int CheckXinerama(_THIS, int *major, int *minor)
+{
+ const char *env;
+
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ env = getenv("SDL_VIDEO_X11_XINERAMA");
+ if ( env && !SDL_atoi(env) ) {
+ return 0;
+ }
+
+ /* Query the extension version */
+ if ( !SDL_NAME(XineramaQueryExtension)(SDL_Display, major, minor) ||
+ !SDL_NAME(XineramaIsActive)(SDL_Display) ) {
+ return 0;
+ }
+ return 1;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+static int CheckXRandR(_THIS, int *major, int *minor)
+{
+ const char *env;
+
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ env = getenv("SDL_VIDEO_X11_XRANDR");
+ if ( env && !SDL_atoi(env) ) {
+ return 0;
+ }
+
+ /* This defaults off now, due to KDE window maximize problems */
+ if ( !env ) {
+ return 0;
+ }
+
+ if ( !SDL_X11_HAVE_XRANDR ) {
+ return 0;
+ }
+
+ /* Query the extension version */
+ if ( !XRRQueryVersion(SDL_Display, major, minor) ) {
+ return 0;
+ }
+ return 1;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+static int CheckVidMode(_THIS, int *major, int *minor)
+{
+ const char *env;
+
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ env = getenv("SDL_VIDEO_X11_VIDMODE");
+ if ( env && !SDL_atoi(env) ) {
+ return 0;
+ }
+
+ /* Metro-X 4.3.0 and earlier has a broken implementation of
+ XF86VidModeGetAllModeLines() - it hangs the client.
+ */
+ if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) {
+ FILE *metro_fp;
+
+ metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r");
+ if ( metro_fp != NULL ) {
+ int major, minor, patch, version, scannum;
+ major = 0; minor = 0; patch = 0;
+ scannum = fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch);
+ fclose(metro_fp);
+ if ( (scannum < 0) || (scannum > 3) ) {
+ return 0; /* we need _something_ useful from fscanf(). */
+ }
+ version = major*100+minor*10+patch;
+ if ( version < 431 ) {
+ return 0;
+ }
+ }
+ }
+
+ /* Query the extension version */
+ vm_error = -1;
+ if ( !SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) ||
+ !SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, major, minor) ) {
+ return 0;
+ }
+ return 1;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+#if SDL_VIDEO_DRIVER_X11_XME
+static int CheckXME(_THIS, int *major, int *minor)
+{
+ const char *env;
+
+ /* Default the extension not available */
+ *major = *minor = 0;
+
+ /* Allow environment override */
+ env = getenv("SDL_VIDEO_X11_VIDMODE");
+ if ( env && !SDL_atoi(env) ) {
+ return 0;
+ }
+
+ /* Query the extension version */
+ if ( !XiGMiscQueryVersion(SDL_Display, major, minor) ) {
+ return 0;
+ }
+ return 1;
+}
+#endif /* SDL_VIDEO_DRIVER_X11_XME */
+
+int X11_GetVideoModes(_THIS)
+{
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ int xinerama_major, xinerama_minor;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ int xrandr_major, xrandr_minor;
+ int nsizes;
+ XRRScreenSize *sizes;
+#endif
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ int vm_major, vm_minor;
+ int nmodes;
+ SDL_NAME(XF86VidModeModeInfo) **modes;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XME
+ int xme_major, xme_minor;
+ int ractive, nummodes;
+ XiGMiscResolutionInfo *modelist;
+#endif
+ int i, n;
+ int screen_w;
+ int screen_h;
+
+ use_xinerama = 0;
+ use_xrandr = 0;
+ use_vidmode = 0;
+ use_xme = 0;
+ screen_w = DisplayWidth(SDL_Display, SDL_Screen);
+ screen_h = DisplayHeight(SDL_Display, SDL_Screen);
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ /* Query Xinerama extention */
+ if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) {
+ /* Find out which screen is the desired one */
+ int desired = -1;
+ int screens;
+ int w, h;
+ SDL_NAME(XineramaScreenInfo) *xinerama;
+
+ const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY");
+ if ( !variable ) {
+ variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
+ }
+ if ( variable ) {
+ desired = SDL_atoi(variable);
+ }
+#ifdef X11MODES_DEBUG
+ printf("X11 detected Xinerama:\n");
+#endif
+ xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
+ for ( i = 0; i < screens; i++ ) {
+#ifdef X11MODES_DEBUG
+ printf("xinerama %d: %dx%d+%d+%d\n",
+ xinerama[i].screen_number,
+ xinerama[i].width, xinerama[i].height,
+ xinerama[i].x_org, xinerama[i].y_org);
+#endif
+ if ( xinerama[i].screen_number == desired ) {
+ use_xinerama = 1;
+ xinerama_info = xinerama[i];
+ }
+ }
+ XFree(xinerama);
+
+ if ( use_xinerama ) {
+ SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *));
+ if ( !SDL_modelist ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ /* Add the full xinerama mode */
+ n = 0;
+ w = xinerama_info.width;
+ h = xinerama_info.height;
+ if ( screen_w > w || screen_h > h) {
+ SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[n] ) {
+ SDL_modelist[n]->x = 0;
+ SDL_modelist[n]->y = 0;
+ SDL_modelist[n]->w = screen_w;
+ SDL_modelist[n]->h = screen_h;
+ ++n;
+ }
+ }
+
+ /* Add the head xinerama mode */
+ SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[n] ) {
+ SDL_modelist[n]->x = 0;
+ SDL_modelist[n]->y = 0;
+ SDL_modelist[n]->w = w;
+ SDL_modelist[n]->h = h;
+ ++n;
+ }
+ SDL_modelist[n] = NULL;
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ /* XRandR */
+ /* require at least XRandR v1.0 (arbitrary) */
+ if ( CheckXRandR(this, &xrandr_major, &xrandr_minor) && (xrandr_major >= 1) )
+ {
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
+ xrandr_major, xrandr_minor);
+#endif
+
+ /* save the screen configuration since we must reference it
+ each time we toggle modes.
+ */
+ screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root);
+
+ /* retrieve the list of resolution */
+ sizes = XRRConfigSizes(screen_config, &nsizes);
+ if (nsizes > 0) {
+ if ( SDL_modelist ) {
+ for ( i = 0; SDL_modelist[i]; ++i ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ }
+ SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *));
+ if ( !SDL_modelist ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ for ( i=0; i < nsizes; i++ ) {
+ if ((SDL_modelist[i] =
+ (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL)
+ break;
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n",
+ i, sizes[i].width, sizes[i].height);
+#endif
+
+ SDL_modelist[i]->x = 0;
+ SDL_modelist[i]->y = 0;
+ SDL_modelist[i]->w = sizes[i].width;
+ SDL_modelist[i]->h = sizes[i].height;
+
+ }
+ /* sort the mode list descending as SDL expects */
+ SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist);
+ SDL_modelist[i] = NULL; /* terminator */
+
+ use_xrandr = xrandr_major * 100 + xrandr_minor;
+ saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
+ }
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ /* XVidMode */
+ if ( !use_xrandr &&
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ (!use_xinerama || xinerama_info.screen_number == -1) &&
+#endif
+ CheckVidMode(this, &vm_major, &vm_minor) &&
+ SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) )
+ {
+#ifdef X11MODES_DEBUG
+ printf("VidMode modes: (unsorted)\n");
+ for ( i = 0; i < nmodes; ++i ) {
+ printf("Mode %d: %d x %d @ %d\n", i,
+ modes[i]->hdisplay, modes[i]->vdisplay,
+ (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 );
+ }
+#endif
+ if ( SDL_modelist ) {
+ for ( i = 0; SDL_modelist[i]; ++i ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ }
+ SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *));
+ if ( !SDL_modelist ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes);
+ n = 0;
+ for ( i=0; i<nmodes; ++i ) {
+ int w, h;
+
+ /* Eliminate duplicate modes with different refresh rates */
+ if ( i > 0 &&
+ modes[i]->hdisplay == modes[i-1]->hdisplay &&
+ modes[i]->vdisplay == modes[i-1]->vdisplay ) {
+ continue;
+ }
+
+ /* Check to see if we should add the screen size (Xinerama) */
+ w = modes[i]->hdisplay;
+ h = modes[i]->vdisplay;
+ if ( (screen_w * screen_h) >= (w * h) ) {
+ if ( (screen_w != w) || (screen_h != h) ) {
+ SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[n] ) {
+ SDL_modelist[n]->x = 0;
+ SDL_modelist[n]->y = 0;
+ SDL_modelist[n]->w = screen_w;
+ SDL_modelist[n]->h = screen_h;
+ ++n;
+ }
+ }
+ screen_w = 0;
+ screen_h = 0;
+ }
+
+ /* Add the size from the video mode list */
+ SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[n] == NULL ) {
+ break;
+ }
+ SDL_modelist[n]->x = 0;
+ SDL_modelist[n]->y = 0;
+ SDL_modelist[n]->w = w;
+ SDL_modelist[n]->h = h;
+ ++n;
+ }
+ SDL_modelist[n] = NULL;
+ XFree(modes);
+
+ use_vidmode = vm_major * 100 + vm_minor;
+ save_mode(this);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+#if SDL_VIDEO_DRIVER_X11_XME
+ /* XiG */
+ modelist = NULL;
+ /* first lets make sure we have the extension, and it's at least v2.0 */
+ if ( CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 &&
+ (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
+ 0, /* view */
+ &ractive, &modelist)) > 1 )
+ { /* then we actually have some */
+ int j;
+
+ /* We get the list already sorted in descending order.
+ We'll copy it in reverse order so SDL is happy */
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
+ nummodes, ractive);
+#endif
+ if ( SDL_modelist ) {
+ for ( i = 0; SDL_modelist[i]; ++i ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ }
+ SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *));
+ if ( !SDL_modelist ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ for ( i=0, j=nummodes-1; j>=0; i++, j-- ) {
+ if ((SDL_modelist[i] =
+ (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL)
+ break;
+#ifdef X11MODES_DEBUG
+ fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
+ i, modelist[i].width, modelist[i].height);
+#endif
+
+ SDL_modelist[i]->x = 0;
+ SDL_modelist[i]->y = 0;
+ SDL_modelist[i]->w = modelist[j].width;
+ SDL_modelist[i]->h = modelist[j].height;
+
+ }
+ SDL_modelist[i] = NULL; /* terminator */
+
+ use_xme = xme_major * 100 + xme_minor;
+ saved_res = modelist[ractive]; /* save the current resolution */
+ }
+ if ( modelist ) {
+ XFree(modelist);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XME */
+
+ {
+ /* It's interesting to note that if we allow 32 bit depths,
+ we get a visual with an alpha mask on composite servers.
+ static int depth_list[] = { 32, 24, 16, 15, 8 };
+ */
+ static int depth_list[] = { 24, 16, 15, 8 };
+ int j, np;
+ int use_directcolor = 1;
+ XPixmapFormatValues *pf;
+
+ /* Search for the visuals in deepest-first order, so that the first
+ will be the richest one */
+ if ( SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) {
+ use_directcolor = 0;
+ }
+ this->hidden->nvisuals = 0;
+ if ( ! add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID")) ) {
+ for ( i=0; i<SDL_arraysize(depth_list); ++i ) {
+ if ( depth_list[i] > 8 ) {
+ if ( use_directcolor ) {
+ add_visual(this, depth_list[i], DirectColor);
+ }
+ add_visual(this, depth_list[i], TrueColor);
+ } else {
+ add_visual(this, depth_list[i], PseudoColor);
+ add_visual(this, depth_list[i], StaticColor);
+ }
+ }
+ add_default_visual(this);
+ }
+ if ( this->hidden->nvisuals == 0 ) {
+ SDL_SetError("Found no sufficiently capable X11 visuals");
+ return -1;
+ }
+
+ /* look up the pixel quantum for each depth */
+ pf = XListPixmapFormats(SDL_Display, &np);
+ for(i = 0; i < this->hidden->nvisuals; i++) {
+ int d = this->hidden->visuals[i].depth;
+ for(j = 0; j < np; j++)
+ if(pf[j].depth == d)
+ break;
+ this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
+ }
+
+ XFree(pf);
+ }
+
+ if ( SDL_modelist == NULL ) {
+ SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *));
+ if ( !SDL_modelist ) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ n = 0;
+ SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[n] ) {
+ SDL_modelist[n]->x = 0;
+ SDL_modelist[n]->y = 0;
+ SDL_modelist[n]->w = screen_w;
+ SDL_modelist[n]->h = screen_h;
+ ++n;
+ }
+ SDL_modelist[n] = NULL;
+ }
+
+#ifdef X11MODES_DEBUG
+ if ( use_xinerama ) {
+ printf("Xinerama is enabled\n");
+ }
+
+ if ( use_xrandr ) {
+ printf("XRandR is enabled\n");
+ }
+
+ if ( use_vidmode ) {
+ printf("VidMode is enabled\n");
+ }
+
+ if ( use_xme ) {
+ printf("Xi Graphics XME fullscreen is enabled\n");
+ }
+
+ if ( SDL_modelist ) {
+ printf("X11 video mode list:\n");
+ for ( i=0; SDL_modelist[i]; ++i ) {
+ printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h);
+ }
+ }
+#endif /* X11MODES_DEBUG */
+
+ return 0;
+}
+
+int X11_SupportedVisual(_THIS, SDL_PixelFormat *format)
+{
+ int i;
+ for(i = 0; i < this->hidden->nvisuals; i++)
+ if(this->hidden->visuals[i].bpp == format->BitsPerPixel)
+ return 1;
+ return 0;
+}
+
+SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ if ( X11_SupportedVisual(this, format) ) {
+ if ( flags & SDL_FULLSCREEN ) {
+ return(SDL_modelist);
+ } else {
+ return((SDL_Rect **)-1);
+ }
+ } else {
+ return((SDL_Rect **)0);
+ }
+}
+
+void X11_FreeVideoModes(_THIS)
+{
+ int i;
+
+ if ( SDL_modelist ) {
+ for ( i=0; SDL_modelist[i]; ++i ) {
+ SDL_free(SDL_modelist[i]);
+ }
+ SDL_free(SDL_modelist);
+ SDL_modelist = NULL;
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ /* Free the Xrandr screen configuration */
+ if ( screen_config ) {
+ XRRFreeScreenConfigInfo(screen_config);
+ screen_config = NULL;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+}
+
+int X11_ResizeFullScreen(_THIS)
+{
+ int x = 0, y = 0;
+ int real_w, real_h;
+ int screen_w;
+ int screen_h;
+
+ screen_w = DisplayWidth(SDL_Display, SDL_Screen);
+ screen_h = DisplayHeight(SDL_Display, SDL_Screen);
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if ( use_xinerama &&
+ window_w <= xinerama_info.width &&
+ window_h <= xinerama_info.height ) {
+ x = xinerama_info.x_org;
+ y = xinerama_info.y_org;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+ if ( currently_fullscreen ) {
+ /* Switch resolution and cover it with the FSwindow */
+ move_cursor_to(this, x, y);
+ set_best_resolution(this, window_w, window_h);
+ move_cursor_to(this, x, y);
+ get_real_resolution(this, &real_w, &real_h);
+ if ( window_w > real_w ) {
+ real_w = MAX(real_w, screen_w);
+ }
+ if ( window_h > real_h ) {
+ real_h = MAX(real_h, screen_h);
+ }
+ XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
+ move_cursor_to(this, real_w/2, real_h/2);
+
+ /* Center and reparent the drawing window */
+ x = (real_w - window_w)/2;
+ y = (real_h - window_h)/2;
+ XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y);
+ /* FIXME: move the mouse to the old relative location */
+ XSync(SDL_Display, True); /* Flush spurious mode change events */
+ }
+ return(1);
+}
+
+void X11_QueueEnterFullScreen(_THIS)
+{
+ switch_waiting = 0x01 | SDL_FULLSCREEN;
+ switch_time = SDL_GetTicks() + 1500;
+#if 0 /* This causes a BadMatch error if the window is iconified (not needed) */
+ XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime);
+#endif
+}
+
+int X11_EnterFullScreen(_THIS)
+{
+ int okay;
+#if 0
+ Window tmpwin, *windows;
+ int i, nwindows;
+#endif
+ int x = 0, y = 0;
+ int real_w, real_h;
+ int screen_w;
+ int screen_h;
+
+ okay = 1;
+ if ( currently_fullscreen ) {
+ return(okay);
+ }
+
+ /* Ungrab the input so that we can move the mouse around */
+ X11_GrabInputNoLock(this, SDL_GRAB_OFF);
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if ( use_xinerama &&
+ window_w <= xinerama_info.width &&
+ window_h <= xinerama_info.height ) {
+ x = xinerama_info.x_org;
+ y = xinerama_info.y_org;
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
+
+ /* Map the fullscreen window to blank the screen */
+ screen_w = DisplayWidth(SDL_Display, SDL_Screen);
+ screen_h = DisplayHeight(SDL_Display, SDL_Screen);
+ get_real_resolution(this, &real_w, &real_h);
+ real_w = MAX(window_w, MAX(real_w, screen_w));
+ real_h = MAX(window_h, MAX(real_h, screen_h));
+ XMoveResizeWindow(SDL_Display, FSwindow,
+ x, y, real_w, real_h);
+ XMapRaised(SDL_Display, FSwindow);
+ X11_WaitMapped(this, FSwindow);
+
+#if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */
+ /* Make sure we got to the top of the window stack */
+ if ( XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin,
+ &windows, &nwindows) && windows ) {
+ /* If not, try to put us there - if fail... oh well */
+ if ( windows[nwindows-1] != FSwindow ) {
+ tmpwin = windows[nwindows-1];
+ for ( i=0; i<nwindows; ++i ) {
+ if ( windows[i] == FSwindow ) {
+ SDL_memcpy(&windows[i], &windows[i+1],
+ (nwindows-i-1)*sizeof(windows[i]));
+ break;
+ }
+ }
+ windows[nwindows-1] = FSwindow;
+ XRestackWindows(SDL_Display, windows, nwindows);
+ XSync(SDL_Display, False);
+ }
+ XFree(windows);
+ }
+#else
+ XRaiseWindow(SDL_Display, FSwindow);
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ /* Save the current video mode */
+ if ( use_vidmode ) {
+ SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, True);
+ save_mode(this);
+ }
+#endif
+ currently_fullscreen = 1;
+
+ /* Set the new resolution */
+ okay = X11_ResizeFullScreen(this);
+ if ( ! okay ) {
+ X11_LeaveFullScreen(this);
+ }
+ /* Set the colormap */
+ if ( SDL_XColorMap ) {
+ XInstallColormap(SDL_Display, SDL_XColorMap);
+ }
+ if ( okay ) {
+ X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN);
+ }
+
+ /* We may need to refresh the screen at this point (no backing store)
+ We also don't get an event, which is why we explicitly refresh. */
+ if ( this->screen ) {
+ if ( this->screen->flags & SDL_OPENGL ) {
+ SDL_PrivateExpose();
+ } else {
+ X11_RefreshDisplay(this);
+ }
+ }
+
+ return(okay);
+}
+
+int X11_LeaveFullScreen(_THIS)
+{
+ if ( currently_fullscreen ) {
+ XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0);
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ if ( use_vidmode ) {
+ restore_mode(this);
+ SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, False);
+ }
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XME
+ if ( use_xme ) {
+ int rw, rh;
+
+ /* check current mode so we can avoid uneccessary mode changes */
+ get_real_resolution(this, &rw, &rh);
+
+ if (rw != saved_res.width || rh != saved_res.height) {
+ XiGMiscChangeResolution(SDL_Display,
+ SDL_Screen,
+ 0, /* view */
+ saved_res.width,
+ saved_res.height,
+ 0);
+ XSync(SDL_Display, False);
+ }
+ }
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ if ( use_xrandr ) {
+ XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
+ saved_size_id, saved_rotation, CurrentTime);
+ }
+#endif
+
+ XUnmapWindow(SDL_Display, FSwindow);
+ X11_WaitUnmapped(this, FSwindow);
+ XSync(SDL_Display, True); /* Flush spurious mode change events */
+ currently_fullscreen = 0;
+ }
+ /* If we get popped out of fullscreen mode for some reason, input_grab
+ will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
+ temporary. In this case, release the grab unless the input has been
+ explicitly grabbed.
+ */
+ X11_GrabInputNoLock(this, this->input_grab & ~SDL_GRAB_FULLSCREEN);
+
+ /* We may need to refresh the screen at this point (no backing store)
+ We also don't get an event, which is why we explicitly refresh. */
+ if ( this->screen ) {
+ if ( this->screen->flags & SDL_OPENGL ) {
+ SDL_PrivateExpose();
+ } else {
+ X11_RefreshDisplay(this);
+ }
+ }
+
+ return(0);
+}
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes_c.h
new file mode 100644
index 0000000..f7780bf
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11modes_c.h
@@ -0,0 +1,43 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* Utilities for getting and setting the X display mode */
+
+#include "SDL_x11video.h"
+
+/* Define this if you want to grab the keyboard in fullscreen mode.
+ If you do not define this, SDL will return from SDL_SetVideoMode()
+ immediately, but will not actually go fullscreen until the window
+ manager is idle.
+*/
+#define GRAB_FULLSCREEN
+
+extern int X11_GetVideoModes(_THIS);
+extern SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+extern void X11_FreeVideoModes(_THIS);
+extern int X11_ResizeFullScreen(_THIS);
+extern void X11_WaitMapped(_THIS, Window win);
+extern void X11_WaitUnmapped(_THIS, Window win);
+extern void X11_QueueEnterFullScreen(_THIS);
+extern int X11_EnterFullScreen(_THIS);
+extern int X11_LeaveFullScreen(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse.c
new file mode 100644
index 0000000..16ad739
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse.c
@@ -0,0 +1,288 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "SDL_mouse.h"
+#include "../../events/SDL_events_c.h"
+#include "../SDL_cursor_c.h"
+#include "SDL_x11dga_c.h"
+#include "SDL_x11mouse_c.h"
+
+
+/* The implementation dependent data for the window manager cursor */
+struct WMcursor {
+ Cursor x_cursor;
+};
+
+
+void X11_FreeWMCursor(_THIS, WMcursor *cursor)
+{
+ if ( SDL_Display != NULL ) {
+ SDL_Lock_EventThread();
+ XFreeCursor(SDL_Display, cursor->x_cursor);
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+ }
+ SDL_free(cursor);
+}
+
+WMcursor *X11_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
+{
+ WMcursor *cursor;
+ XGCValues GCvalues;
+ GC GCcursor;
+ XImage *data_image, *mask_image;
+ Pixmap data_pixmap, mask_pixmap;
+ int clen, i;
+ char *x_data, *x_mask;
+ static XColor black = { 0, 0, 0, 0 };
+ static XColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
+
+ /* Allocate the cursor memory */
+ cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor));
+ if ( cursor == NULL ) {
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+
+ /* Mix the mask and the data */
+ clen = (w/8)*h;
+ x_data = (char *)SDL_malloc(clen);
+ if ( x_data == NULL ) {
+ SDL_free(cursor);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ x_mask = (char *)SDL_malloc(clen);
+ if ( x_mask == NULL ) {
+ SDL_free(cursor);
+ SDL_free(x_data);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ for ( i=0; i<clen; ++i ) {
+ /* The mask is OR'd with the data to turn inverted color
+ pixels black since inverted color cursors aren't supported
+ under X11.
+ */
+ x_mask[i] = data[i] | mask[i];
+ x_data[i] = data[i];
+ }
+
+ /* Prevent the event thread from running while we use the X server */
+ SDL_Lock_EventThread();
+
+ /* Create the data image */
+ data_image = XCreateImage(SDL_Display,
+ DefaultVisual(SDL_Display, SDL_Screen),
+ 1, XYBitmap, 0, x_data, w, h, 8, w/8);
+ data_image->byte_order = MSBFirst;
+ data_image->bitmap_bit_order = MSBFirst;
+ data_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1);
+
+ /* Create the data mask */
+ mask_image = XCreateImage(SDL_Display,
+ DefaultVisual(SDL_Display, SDL_Screen),
+ 1, XYBitmap, 0, x_mask, w, h, 8, w/8);
+ mask_image->byte_order = MSBFirst;
+ mask_image->bitmap_bit_order = MSBFirst;
+ mask_pixmap = XCreatePixmap(SDL_Display, SDL_Root, w, h, 1);
+
+ /* Create the graphics context */
+ GCvalues.function = GXcopy;
+ GCvalues.foreground = ~0;
+ GCvalues.background = 0;
+ GCvalues.plane_mask = AllPlanes;
+ GCcursor = XCreateGC(SDL_Display, data_pixmap,
+ (GCFunction|GCForeground|GCBackground|GCPlaneMask),
+ &GCvalues);
+
+ /* Blit the images to the pixmaps */
+ XPutImage(SDL_Display, data_pixmap, GCcursor, data_image,
+ 0, 0, 0, 0, w, h);
+ XPutImage(SDL_Display, mask_pixmap, GCcursor, mask_image,
+ 0, 0, 0, 0, w, h);
+ XFreeGC(SDL_Display, GCcursor);
+ /* These free the x_data and x_mask memory pointers */
+ XDestroyImage(data_image);
+ XDestroyImage(mask_image);
+
+ /* Create the cursor */
+ cursor->x_cursor = XCreatePixmapCursor(SDL_Display, data_pixmap,
+ mask_pixmap, &black, &white, hot_x, hot_y);
+ XFreePixmap(SDL_Display, data_pixmap);
+ XFreePixmap(SDL_Display, mask_pixmap);
+
+ /* Release the event thread */
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+
+ return(cursor);
+}
+
+int X11_ShowWMCursor(_THIS, WMcursor *cursor)
+{
+ /* Don't do anything if the display is gone */
+ if ( SDL_Display == NULL ) {
+ return(0);
+ }
+
+ /* Set the X11 cursor cursor, or blank if cursor is NULL */
+ if ( SDL_Window ) {
+ SDL_Lock_EventThread();
+ if ( cursor == NULL ) {
+ if ( SDL_BlankCursor != NULL ) {
+ XDefineCursor(SDL_Display, SDL_Window,
+ SDL_BlankCursor->x_cursor);
+ }
+ } else {
+ XDefineCursor(SDL_Display, SDL_Window, cursor->x_cursor);
+ }
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+ }
+ return(1);
+}
+
+void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+{
+ if ( using_dga & DGA_MOUSE ) {
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ } else if ( mouse_relative) {
+ /* RJR: March 28, 2000
+ leave physical cursor at center of screen if
+ mouse hidden and grabbed */
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ } else {
+ SDL_Lock_EventThread();
+ XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, x, y);
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+ }
+}
+
+/* Sets the mouse acceleration from a string of the form:
+ 2/1/0
+ The first number is the numerator, followed by the acceleration
+ denumenator and threshold.
+*/
+static void SetMouseAccel(_THIS, const char *accel_param)
+{
+ int i;
+ size_t len;
+ int accel_value[3];
+ char *mouse_param, *mouse_param_buf, *pin;
+
+ len = SDL_strlen(accel_param)+1;
+ mouse_param_buf = SDL_stack_alloc(char, len);
+ if ( ! mouse_param_buf ) {
+ return;
+ }
+ SDL_strlcpy(mouse_param_buf, accel_param, len);
+ mouse_param = mouse_param_buf;
+
+ for ( i=0; (i < 3) && mouse_param; ++i ) {
+ pin = SDL_strchr(mouse_param, '/');
+ if ( pin ) {
+ *pin = '\0';
+ }
+ accel_value[i] = atoi(mouse_param);
+ if ( pin ) {
+ mouse_param = pin+1;
+ } else {
+ mouse_param = NULL;
+ }
+ }
+ if ( i == 3 ) {
+ XChangePointerControl(SDL_Display, True, True,
+ accel_value[0], accel_value[1], accel_value[2]);
+ }
+ SDL_stack_free(mouse_param_buf);
+}
+
+/* Check to see if we need to enter or leave mouse relative mode */
+void X11_CheckMouseModeNoLock(_THIS)
+{
+ const Uint8 full_focus = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
+ char *env_override;
+ int enable_relative = 1;
+
+ /* This happens when quiting after an xio error */
+ if ( SDL_Display == NULL )
+ return;
+
+ /* Allow the user to override the relative mouse mode.
+ They almost never want to do this, as it seriously affects
+ applications that rely on continuous relative mouse motion.
+ */
+ env_override = SDL_getenv("SDL_MOUSE_RELATIVE");
+ if ( env_override ) {
+ enable_relative = atoi(env_override);
+ }
+
+ /* If the mouse is hidden and input is grabbed, we use relative mode */
+ if ( enable_relative &&
+ !(SDL_cursorstate & CURSOR_VISIBLE) &&
+ (this->input_grab != SDL_GRAB_OFF) &&
+ (SDL_GetAppState() & full_focus) == full_focus ) {
+ if ( ! mouse_relative ) {
+ X11_EnableDGAMouse(this);
+ if ( ! (using_dga & DGA_MOUSE) ) {
+ char *xmouse_accel;
+
+ SDL_GetMouseState(&mouse_last.x, &mouse_last.y);
+ /* Use as raw mouse mickeys as possible */
+ XGetPointerControl(SDL_Display,
+ &mouse_accel.numerator,
+ &mouse_accel.denominator,
+ &mouse_accel.threshold);
+ xmouse_accel=SDL_getenv("SDL_VIDEO_X11_MOUSEACCEL");
+ if ( xmouse_accel ) {
+ SetMouseAccel(this, xmouse_accel);
+ }
+ }
+ mouse_relative = 1;
+ }
+ } else {
+ if ( mouse_relative ) {
+ if ( using_dga & DGA_MOUSE ) {
+ X11_DisableDGAMouse(this);
+ } else {
+ XChangePointerControl(SDL_Display, True, True,
+ mouse_accel.numerator,
+ mouse_accel.denominator,
+ mouse_accel.threshold);
+ }
+ mouse_relative = 0;
+ }
+ }
+}
+void X11_CheckMouseMode(_THIS)
+{
+ SDL_Lock_EventThread();
+ X11_CheckMouseModeNoLock(this);
+ SDL_Unlock_EventThread();
+}
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse_c.h
new file mode 100644
index 0000000..03d97d8
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11mouse_c.h
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+
+/* Functions to be exported */
+extern void X11_FreeWMCursor(_THIS, WMcursor *cursor);
+extern WMcursor *X11_CreateWMCursor(_THIS,
+ Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
+extern int X11_ShowWMCursor(_THIS, WMcursor *cursor);
+extern void X11_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
+extern void X11_CheckMouseModeNoLock(_THIS);
+extern void X11_CheckMouseMode(_THIS);
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h
new file mode 100644
index 0000000..f9c7df3
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h
@@ -0,0 +1,211 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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
+*/
+
+SDL_X11_MODULE(BASEXLIB)
+SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return)
+SDL_X11_SYM(Status,XAllocColor,(Display* a,Colormap b,XColor* c),(a,b,c),return)
+SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return)
+SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return)
+SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(int,XChangeWindowAttributes,(Display* a,Window b,unsigned long c,XSetWindowAttributes* d),(a,b,c,d),return)
+SDL_X11_SYM(Bool,XCheckTypedEvent,(Display* a,int b,XEvent* c),(a,b,c),return)
+SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return)
+SDL_X11_SYM(int,XConfigureWindow,(Display* a,Window b,unsigned int c,XWindowChanges* d),(a,b,c,d),return)
+SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
+SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
+SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return)
+SDL_X11_SYM(Pixmap,XCreatePixmap,(Display* a,Drawable b,unsigned int c,unsigned int d,unsigned int e),(a,b,c,d,e),return)
+SDL_X11_SYM(Pixmap,XCreatePixmapFromBitmapData,(Display* a,Drawable b,char* c,unsigned int d,unsigned int e,unsigned long f,unsigned long g,unsigned int h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(Window,XCreateSimpleWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,unsigned long h,unsigned long i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
+SDL_X11_SYM(int,XDefaultScreen,(Display* a),(a),return)
+SDL_X11_SYM(int,XDisplayWidth,(Display* a,int b),(a,b),return)
+SDL_X11_SYM(int,XDisplayWidthMM,(Display* a, int b),(a, b),return)
+SDL_X11_SYM(int,XDisplayHeight,(Display* a,int b),(a,b),return)
+SDL_X11_SYM(int,XDisplayHeightMM,(Display* a, int b),(a, b),return)
+SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return)
+SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return)
+SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return)
+SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return)
+SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event, Window w),(event,w),return)
+SDL_X11_SYM(int,XFlush,(Display* a),(a),return)
+SDL_X11_SYM(int,XFree,(void*a),(a),return)
+SDL_X11_SYM(int,XFreeColormap,(Display* a,Colormap b),(a,b),return)
+SDL_X11_SYM(int,XFreeColors,(Display* a,Colormap b,unsigned long* c,int d,unsigned long e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return)
+SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
+SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
+SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
+SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XGetGeometry,(Display* a,Drawable b,Window* c,int* d,int* e,unsigned int* f,unsigned int* g,unsigned int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
+SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
+SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
+SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
+SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return)
+SDL_X11_SYM(Status,XInitThreads,(void),(),return)
+SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return)
+SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return)
+SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return)
+SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return)
+SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XMapWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XMaskEvent,(Display* a,long b,XEvent* c),(a,b,c),return)
+SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return)
+SDL_X11_SYM(int,XMoveResizeWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return)
+SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return)
+SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return)
+SDL_X11_SYM(int,XPending,(Display* a),(a),return)
+SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j),(a,b,c,d,e,f,g,h,i,j),return)
+SDL_X11_SYM(int,XQueryColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return)
+SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return)
+SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return)
+SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,XSetClassHint,(Display* a,Window b,XClassHint* c),(a,b,c),return)
+SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return)
+SDL_X11_SYM(XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler a),(a),return)
+SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return)
+SDL_X11_SYM(int,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),return)
+SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),)
+SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),)
+SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return)
+SDL_X11_SYM(int,XSetWindowBackgroundPixmap,(Display* a,Window b,Pixmap c),(a,b,c),return)
+SDL_X11_SYM(int,XSetWindowColormap,(Display* a,Window b,Colormap c),(a,b,c),return)
+SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XStringListToTextProperty,(char** a,int b,XTextProperty* c),(a,b,c),return)
+SDL_X11_SYM(int,XSync,(Display* a,Bool b),(a,b),return)
+SDL_X11_SYM(int,XUngrabKeyboard,(Display* a,Time b),(a,b),return)
+SDL_X11_SYM(int,XUngrabPointer,(Display* a,Time b),(a,b),return)
+SDL_X11_SYM(int,XUnmapWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned int f,unsigned int g,int h, int i),(a,b,c,d,e,f,g,h,i),return)
+SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return)
+SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
+SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return)
+SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),)
+SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
+SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
+SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return)
+SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return)
+SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return)
+SDL_X11_SYM(void,_XEatData,(Display* a,unsigned long b),(a,b),)
+SDL_X11_SYM(void,_XFlush,(Display* a),(a),)
+SDL_X11_SYM(void,_XFlushGCCache,(Display* a,GC b),(a,b),)
+SDL_X11_SYM(int,_XRead,(Display* a,char* b,long c),(a,b,c),return)
+SDL_X11_SYM(void,_XReadPad,(Display* a,char* b,long c),(a,b,c),)
+SDL_X11_SYM(void,_XSend,(Display* a,_Xconst char* b,long c),(a,b,c),)
+SDL_X11_SYM(Status,_XReply,(Display* a,xReply* b,int c,Bool d),(a,b,c,d),return)
+SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,b),return)
+SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return)
+SDL_X11_SYM(int,XTranslateCoordinates,(Display* a,Window b,Window c,int d,int e,int* f,int* g,Window* h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return)
+SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
+SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
+
+#if NeedWidePrototypes
+SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
+#else
+SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,KeyCode b,int c),(a,b,c),return)
+#endif
+
+#ifdef X_HAVE_UTF8_STRING
+SDL_X11_MODULE(UTF8)
+SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return)
+SDL_X11_SYM(int,Xutf8LookupString,(XIC a,XKeyPressedEvent* b,char* c,int d,KeySym* e,Status* f),(a,b,c,d,e,f),return)
+/*SDL_X11_SYM(XIC,XCreateIC,(XIM, ...),return) !!! ARGH! */
+SDL_X11_SYM(void,XDestroyIC,(XIC a),(a),)
+SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
+SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
+/*SDL_X11_SYM(char*,XGetICValues,(XIC a, ...),return)*/
+SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
+SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return)
+SDL_X11_SYM(char*,XSetLocaleModifiers,(_Xconst char* a),(a),return)
+SDL_X11_SYM(int,XRefreshKeyboardMapping,(XMappingEvent* a),(a),return)
+SDL_X11_SYM(Display*,XDisplayOfIM,(XIM a),(a),return)
+#endif
+
+#ifndef NO_SHARED_MEMORY
+SDL_X11_MODULE(SHM)
+SDL_X11_SYM(Status,XShmAttach,(Display* a,XShmSegmentInfo* b),(a,b),return)
+SDL_X11_SYM(Status,XShmDetach,(Display* a,XShmSegmentInfo* b),(a,b),return)
+SDL_X11_SYM(Status,XShmPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j,Bool k),(a,b,c,d,e,f,g,h,i,j,k),return)
+SDL_X11_SYM(XImage*,XShmCreateImage,(Display* a,Visual* b,unsigned int c,int d,char* e,XShmSegmentInfo* f,unsigned int g,unsigned int h),(a,b,c,d,e,f,g,h),return)
+SDL_X11_SYM(Bool,XShmQueryExtension,(Display* a),(a),return)
+#endif
+
+/*
+ * Not required...these only exist in code in headers on some 64-bit platforms,
+ * and are removed via macros elsewhere, so it's safe for them to be missing.
+ */
+#ifdef LONG64
+SDL_X11_MODULE(IO_32BIT)
+SDL_X11_SYM(int,_XData32,(Display *dpy,register long *data,unsigned len),(dpy,data,len),return)
+SDL_X11_SYM(void,_XRead32,(Display *dpy,register long *data,long len),(dpy,data,len),)
+#endif
+
+/*
+ * libX11 1.4.99.1 added _XGetRequest, and macros use it behind the scenes.
+ */
+SDL_X11_MODULE(XGETREQUEST)
+SDL_X11_SYM(void *,_XGetRequest,(Display* a,CARD8 b,size_t c),(a,b,c),return)
+
+/*
+ * These only show up on some variants of Unix.
+ */
+#if defined(__osf__)
+SDL_X11_MODULE(OSF_ENTRY_POINTS)
+SDL_X11_SYM(void,_SmtBufferOverflow,(Display *dpy,register smtDisplayPtr p),(dpy,p),)
+SDL_X11_SYM(void,_SmtIpError,(Display *dpy,register smtDisplayPtr p, int i),(dpy,p,i),)
+SDL_X11_SYM(int,ipAllocateData,(ChannelPtr a, IPCard b, IPDataPtr * c),(a,b,c),return)
+SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a, IPCard b),(a,b),return)
+#endif
+
+/* Xrandr support. */
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+SDL_X11_MODULE(XRANDR)
+SDL_X11_SYM(Status,XRRQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return)
+SDL_X11_SYM(XRRScreenConfiguration *,XRRGetScreenInfo,(Display *dpy,Drawable draw),(dpy,draw),return)
+SDL_X11_SYM(SizeID,XRRConfigCurrentConfiguration,(XRRScreenConfiguration *config,Rotation *rotation),(config,rotation),return)
+SDL_X11_SYM(XRRScreenSize *,XRRConfigSizes,(XRRScreenConfiguration *config, int *nsizes),(config,nsizes),return)
+SDL_X11_SYM(Status,XRRSetScreenConfig,(Display *dpy, XRRScreenConfiguration *config, Drawable draw, int size_index, Rotation rotation, Time timestamp),(dpy,config,draw,size_index,rotation,timestamp),return)
+SDL_X11_SYM(void,XRRFreeScreenConfigInfo,(XRRScreenConfiguration *config),(config),)
+#endif
+
+/* end of SDL_x11sym.h ... */
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c
new file mode 100644
index 0000000..6d24422
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c
@@ -0,0 +1,1580 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* X11 based SDL video driver implementation.
+ Note: This implementation does not currently need X11 thread locking,
+ since the event thread uses a separate X connection and any
+ additional locking necessary is handled internally. However,
+ if full locking is neccessary, take a look at XInitThreads().
+*/
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#ifdef MTRR_SUPPORT
+#include <asm/mtrr.h>
+#include <sys/fcntl.h>
+#endif
+
+#include "SDL_endian.h"
+#include "SDL_timer.h"
+#include "SDL_thread.h"
+#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_x11video.h"
+#include "SDL_x11wm_c.h"
+#include "SDL_x11mouse_c.h"
+#include "SDL_x11events_c.h"
+#include "SDL_x11modes_c.h"
+#include "SDL_x11image_c.h"
+#include "SDL_x11yuv_c.h"
+#include "SDL_x11gl_c.h"
+#include "SDL_x11gamma_c.h"
+#include "../blank_cursor.h"
+
+#ifdef X_HAVE_UTF8_STRING
+#include <locale.h>
+#endif
+
+/* Initialization/Query functions */
+static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int X11_ToggleFullScreen(_THIS, int on);
+static void X11_UpdateMouse(_THIS);
+static int X11_SetColors(_THIS, int firstcolor, int ncolors,
+ SDL_Color *colors);
+static int X11_SetGammaRamp(_THIS, Uint16 *ramp);
+static void X11_VideoQuit(_THIS);
+
+int X11_wmXAdjust;
+int X11_wmYAdjust;
+
+/* X11 driver bootstrap functions */
+
+static int X11_Available(void)
+{
+ Display *display = NULL;
+ if ( SDL_X11_LoadSymbols() ) {
+ display = XOpenDisplay(NULL);
+ if ( display != NULL ) {
+ XCloseDisplay(display);
+ }
+ SDL_X11_UnloadSymbols();
+ }
+ return(display != NULL);
+}
+
+static void X11_DeleteDevice(SDL_VideoDevice *device)
+{
+ if ( device ) {
+ if ( device->hidden ) {
+ SDL_free(device->hidden);
+ }
+ if ( device->gl_data ) {
+ SDL_free(device->gl_data);
+ }
+ SDL_free(device);
+ SDL_X11_UnloadSymbols();
+ }
+}
+
+static SDL_VideoDevice *X11_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device = NULL;
+
+ if ( SDL_X11_LoadSymbols() ) {
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ device->gl_data = (struct SDL_PrivateGLData *)
+ SDL_malloc((sizeof *device->gl_data));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ||
+ (device->gl_data == NULL) ) {
+ SDL_OutOfMemory();
+ X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
+
+#if SDL_VIDEO_OPENGL_GLX
+ device->gl_data->swap_interval = -1;
+#endif
+
+ /* Set the driver flags */
+ device->handles_any_size = 1;
+
+ /* Set the function pointers */
+ device->VideoInit = X11_VideoInit;
+ device->ListModes = X11_ListModes;
+ device->SetVideoMode = X11_SetVideoMode;
+ device->ToggleFullScreen = X11_ToggleFullScreen;
+ device->UpdateMouse = X11_UpdateMouse;
+#if SDL_VIDEO_DRIVER_X11_XV
+ device->CreateYUVOverlay = X11_CreateYUVOverlay;
+#endif
+ device->SetColors = X11_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = X11_VideoQuit;
+ device->AllocHWSurface = X11_AllocHWSurface;
+ device->CheckHWBlit = NULL;
+ device->FillHWRect = NULL;
+ device->SetHWColorKey = NULL;
+ device->SetHWAlpha = NULL;
+ device->LockHWSurface = X11_LockHWSurface;
+ device->UnlockHWSurface = X11_UnlockHWSurface;
+ device->FlipHWSurface = X11_FlipHWSurface;
+ device->FreeHWSurface = X11_FreeHWSurface;
+ device->SetGamma = X11_SetVidModeGamma;
+ device->GetGamma = X11_GetVidModeGamma;
+ device->SetGammaRamp = X11_SetGammaRamp;
+ device->GetGammaRamp = NULL;
+#if SDL_VIDEO_OPENGL_GLX
+ device->GL_LoadLibrary = X11_GL_LoadLibrary;
+ device->GL_GetProcAddress = X11_GL_GetProcAddress;
+ device->GL_GetAttribute = X11_GL_GetAttribute;
+ device->GL_MakeCurrent = X11_GL_MakeCurrent;
+ device->GL_SwapBuffers = X11_GL_SwapBuffers;
+#endif
+ device->SetCaption = X11_SetCaption;
+ device->SetIcon = X11_SetIcon;
+ device->IconifyWindow = X11_IconifyWindow;
+ device->GrabInput = X11_GrabInput;
+ device->GetWindowPos = X11_GetWindowPos;
+ device->SetWindowPos = X11_SetWindowPos;
+ device->IsWindowVisible = X11_IsWindowVisible;
+ device->GetMonitorDPI = X11_GetMonitorDPI;
+ device->GetMonitorRect = X11_GetMonitorRect;
+ device->GetWMInfo = X11_GetWMInfo;
+ device->FreeWMCursor = X11_FreeWMCursor;
+ device->CreateWMCursor = X11_CreateWMCursor;
+ device->ShowWMCursor = X11_ShowWMCursor;
+ device->WarpWMCursor = X11_WarpWMCursor;
+ device->CheckMouseMode = X11_CheckMouseMode;
+ device->InitOSKeymap = X11_InitOSKeymap;
+ device->PumpEvents = X11_PumpEvents;
+
+ device->free = X11_DeleteDevice;
+ }
+
+ return device;
+}
+
+VideoBootStrap X11_bootstrap = {
+ "x11", "X Window System",
+ X11_Available, X11_CreateDevice
+};
+
+/* Normal X11 error handler routine */
+static int (*X_handler)(Display *, XErrorEvent *) = NULL;
+static int x_errhandler(Display *d, XErrorEvent *e)
+{
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ extern int vm_error;
+#endif
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+ extern int dga_error;
+#endif
+
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ /* VidMode errors are non-fatal. :) */
+ /* Are the errors offset by one from the error base?
+ e.g. the error base is 143, the code is 148, and the
+ actual error is XF86VidModeExtensionDisabled (4) ?
+ */
+ if ( (vm_error >= 0) &&
+ (((e->error_code == BadRequest)&&(e->request_code == vm_error)) ||
+ ((e->error_code > vm_error) &&
+ (e->error_code <= (vm_error+XF86VidModeNumberErrors)))) ) {
+#ifdef X11_DEBUG
+{ char errmsg[1024];
+ XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
+printf("VidMode error: %s\n", errmsg);
+}
+#endif
+ return(0);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
+
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+ /* DGA errors can be non-fatal. :) */
+ if ( (dga_error >= 0) &&
+ ((e->error_code > dga_error) &&
+ (e->error_code <= (dga_error+XF86DGANumberErrors))) ) {
+#ifdef X11_DEBUG
+{ char errmsg[1024];
+ XGetErrorText(d, e->error_code, errmsg, sizeof(errmsg));
+printf("DGA error: %s\n", errmsg);
+}
+#endif
+ return(0);
+ }
+#endif /* SDL_VIDEO_DRIVER_X11_DGAMOUSE */
+
+ return(X_handler(d,e));
+}
+
+/* X11 I/O error handler routine */
+static int (*XIO_handler)(Display *) = NULL;
+static int xio_errhandler(Display *d)
+{
+ /* Ack! Lost X11 connection! */
+
+ /* We will crash if we try to clean up our display */
+ if ( SDL_VideoSurface && current_video->hidden->Ximage ) {
+ SDL_VideoSurface->pixels = NULL;
+ }
+ current_video->hidden->X11_Display = NULL;
+
+ /* Continue with the standard X11 error handler */
+ return(XIO_handler(d));
+}
+
+static int (*Xext_handler)(Display *, _Xconst char *, _Xconst char *) = NULL;
+static int xext_errhandler(Display *d, _Xconst char *ext, _Xconst char *reason)
+{
+#ifdef X11_DEBUG
+ printf("Xext error inside SDL (may be harmless):\n");
+ printf(" Extension \"%s\" %s on display \"%s\".\n",
+ ext, reason, XDisplayString(d));
+#endif
+
+ if (SDL_strcmp(reason, "missing") == 0) {
+ /*
+ * Since the query itself, elsewhere, can handle a missing extension
+ * and the default behaviour in Xlib is to write to stderr, which
+ * generates unnecessary bug reports, we just ignore these.
+ */
+ return 0;
+ }
+
+ /* Everything else goes to the default handler... */
+ return Xext_handler(d, ext, reason);
+}
+
+/* Find out what class name we should use */
+static char *get_classname(char *classname, int maxlen)
+{
+ char *spot;
+#if defined(__LINUX__) || defined(__FREEBSD__)
+ char procfile[1024];
+ char linkfile[1024];
+ int linksize;
+#endif
+
+ /* First allow environment variable override */
+ spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
+ if ( spot ) {
+ SDL_strlcpy(classname, spot, maxlen);
+ return classname;
+ }
+
+ /* Next look at the application's executable name */
+#if defined(__LINUX__) || defined(__FREEBSD__)
+#if defined(__LINUX__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
+#elif defined(__FREEBSD__)
+ SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid());
+#else
+#error Where can we find the executable name?
+#endif
+ linksize = readlink(procfile, linkfile, sizeof(linkfile)-1);
+ if ( linksize > 0 ) {
+ linkfile[linksize] = '\0';
+ spot = SDL_strrchr(linkfile, '/');
+ if ( spot ) {
+ SDL_strlcpy(classname, spot+1, maxlen);
+ } else {
+ SDL_strlcpy(classname, linkfile, maxlen);
+ }
+ return classname;
+ }
+#endif /* __LINUX__ */
+
+ /* Finally use the default we've used forever */
+ SDL_strlcpy(classname, "SDL_App", maxlen);
+ return classname;
+}
+
+/* Create auxiliary (toplevel) windows with the current visual */
+static void create_aux_windows(_THIS)
+{
+ int x = 0, y = 0;
+ char classname[1024];
+ XSetWindowAttributes xattr;
+ XWMHints *hints;
+ unsigned long app_event_mask;
+ int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));
+
+ /* Look up some useful Atoms */
+ WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
+
+ /* Don't create any extra windows if we are being managed */
+ if ( SDL_windowid ) {
+ FSwindow = 0;
+ WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
+ return;
+ }
+
+ if(FSwindow)
+ XDestroyWindow(SDL_Display, FSwindow);
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if ( use_xinerama ) {
+ x = xinerama_info.x_org;
+ y = xinerama_info.y_org;
+ }
+#endif
+ xattr.override_redirect = True;
+ xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
+ xattr.border_pixel = 0;
+ xattr.colormap = SDL_XColorMap;
+
+ FSwindow = XCreateWindow(SDL_Display, SDL_Root,
+ x + X11_wmXAdjust,
+ y + X11_wmYAdjust,
+ 32, 32, 0,
+ this->hidden->depth, InputOutput, SDL_Visual,
+ CWOverrideRedirect | CWBackPixel | CWBorderPixel
+ | CWColormap,
+ &xattr);
+
+ XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);
+
+ /* Tell KDE to keep the fullscreen window on top */
+ {
+ XEvent ev;
+ long mask;
+
+ SDL_memset(&ev, 0, sizeof(ev));
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = SDL_Root;
+ ev.xclient.message_type = XInternAtom(SDL_Display,
+ "KWM_KEEP_ON_TOP", False);
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = FSwindow;
+ ev.xclient.data.l[1] = CurrentTime;
+ mask = SubstructureRedirectMask;
+ XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
+ }
+
+ hints = NULL;
+ if(WMwindow) {
+ /* All window attributes must survive the recreation */
+ hints = XGetWMHints(SDL_Display, WMwindow);
+ XDestroyWindow(SDL_Display, WMwindow);
+ }
+
+ /* Create the window for windowed management */
+ /* (reusing the xattr structure above) */
+ WMwindow = XCreateWindow(SDL_Display, SDL_Root,
+ x, y, 32, 32, 0,
+ this->hidden->depth, InputOutput, SDL_Visual,
+ CWBackPixel | CWBorderPixel | CWColormap,
+ &xattr);
+
+ /* Set the input hints so we get keyboard input */
+ if(!hints) {
+ hints = XAllocWMHints();
+ hints->input = True;
+ hints->flags = InputHint;
+ }
+ XSetWMHints(SDL_Display, WMwindow, hints);
+ XFree(hints);
+ X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);
+
+ app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
+ | PropertyChangeMask | StructureNotifyMask | KeymapStateMask;
+ XSelectInput(SDL_Display, WMwindow, app_event_mask);
+
+ /* Set the class hints so we can get an icon (AfterStep) */
+ get_classname(classname, sizeof(classname));
+ {
+ XClassHint *classhints;
+ classhints = XAllocClassHint();
+ if(classhints != NULL) {
+ classhints->res_name = classname;
+ classhints->res_class = classname;
+ XSetClassHint(SDL_Display, WMwindow, classhints);
+ XFree(classhints);
+ }
+ }
+
+ {
+ pid_t pid = getpid();
+ char hostname[256];
+
+ if (pid > 0 && gethostname(hostname, sizeof(hostname)) > -1) {
+ Atom _NET_WM_PID = XInternAtom(SDL_Display, "_NET_WM_PID", False);
+ Atom WM_CLIENT_MACHINE = XInternAtom(SDL_Display, "WM_CLIENT_MACHINE", False);
+
+ hostname[sizeof(hostname)-1] = '\0';
+ XChangeProperty(SDL_Display, WMwindow, _NET_WM_PID, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *)&pid, 1);
+ XChangeProperty(SDL_Display, WMwindow, WM_CLIENT_MACHINE, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)hostname, SDL_strlen(hostname));
+ }
+ }
+
+ /* Setup the communication with the IM server */
+ /* create_aux_windows may be called several times against the same
+ Display. We should reuse the SDL_IM if one has been opened for
+ the Display, so we should not simply reset SDL_IM here. */
+
+ #ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ /* Discard obsolete resources if any. */
+ if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {
+ /* Just a double check. I don't think this
+ code is ever executed. */
+ SDL_SetError("display has changed while an IM is kept");
+ if (SDL_IC) {
+ XUnsetICFocus(SDL_IC);
+ XDestroyIC(SDL_IC);
+ SDL_IC = NULL;
+ }
+ XCloseIM(SDL_IM);
+ SDL_IM = NULL;
+ }
+
+ /* Open an input method. */
+ if (SDL_IM == NULL) {
+ char *old_locale = NULL, *old_modifiers = NULL;
+ const char *p;
+ size_t n;
+ /* I'm not comfortable to do locale setup
+ here. However, we need C library locale
+ (and xlib modifiers) to be set based on the
+ user's preference to use XIM, and many
+ existing game programs doesn't take care of
+ users' locale preferences, so someone other
+ than the game program should do it.
+ Moreover, ones say that some game programs
+ heavily rely on the C locale behaviour,
+ e.g., strcol()'s, and we can't change the C
+ library locale. Given the situation, I
+ couldn't find better place to do the
+ job... */
+
+ /* Save the current (application program's)
+ locale settings. */
+ p = setlocale(LC_ALL, NULL);
+ if ( p ) {
+ n = SDL_strlen(p)+1;
+ old_locale = SDL_stack_alloc(char, n);
+ if ( old_locale ) {
+ SDL_strlcpy(old_locale, p, n);
+ }
+ }
+ p = XSetLocaleModifiers(NULL);
+ if ( p ) {
+ n = SDL_strlen(p)+1;
+ old_modifiers = SDL_stack_alloc(char, n);
+ if ( old_modifiers ) {
+ SDL_strlcpy(old_modifiers, p, n);
+ }
+ }
+
+ /* Fetch the user's preferences and open the
+ input method with them. */
+ setlocale(LC_ALL, "");
+ XSetLocaleModifiers("");
+ SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);
+
+ /* Restore the application's locale settings
+ so that we don't break the application's
+ expected behaviour. */
+ if ( old_locale ) {
+ /* We need to restore the C library
+ locale first, since the
+ interpretation of the X modifier
+ may depend on it. */
+ setlocale(LC_ALL, old_locale);
+ SDL_stack_free(old_locale);
+ }
+ if ( old_modifiers ) {
+ XSetLocaleModifiers(old_modifiers);
+ SDL_stack_free(old_modifiers);
+ }
+ }
+
+ /* Create a new input context for the new window just created. */
+ if (SDL_IM == NULL) {
+ SDL_SetError("no input method could be opened");
+ } else {
+ if (SDL_IC != NULL) {
+ /* Discard the old IC before creating new one. */
+ XUnsetICFocus(SDL_IC);
+ XDestroyIC(SDL_IC);
+ }
+ /* Theoretically we should check the current IM supports
+ PreeditNothing+StatusNothing style (i.e., root window method)
+ before creating the IC. However, it is the bottom line method,
+ and we supports any other options. If the IM didn't support
+ root window method, the following call fails, and SDL falls
+ back to pre-XIM keyboard handling. */
+ SDL_IC = pXCreateIC(SDL_IM,
+ XNClientWindow, WMwindow,
+ XNFocusWindow, WMwindow,
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNResourceName, classname,
+ XNResourceClass, classname,
+ NULL);
+
+ if (SDL_IC == NULL) {
+ SDL_SetError("no input context could be created");
+ XCloseIM(SDL_IM);
+ SDL_IM = NULL;
+ } else {
+ /* We need to receive X events that an IM wants and to pass
+ them to the IM through XFilterEvent. The set of events may
+ vary depending on the IM implementation and the options
+ specified through various routes. Although unlikely, the
+ xlib specification allows IM to change the event requirement
+ with its own circumstances, it is safe to call SelectInput
+ whenever we re-create an IC. */
+ unsigned long mask = 0;
+ char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL);
+ if (ret != NULL) {
+ XUnsetICFocus(SDL_IC);
+ XDestroyIC(SDL_IC);
+ SDL_IC = NULL;
+ SDL_SetError("no input context could be created");
+ XCloseIM(SDL_IM);
+ SDL_IM = NULL;
+ } else {
+ XSelectInput(SDL_Display, WMwindow, app_event_mask | mask);
+ XSetICFocus(SDL_IC);
+ }
+ }
+ }
+ }
+ #endif
+
+ /* Allow the window to be deleted by the window manager */
+ XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
+}
+
+static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ const char *env;
+ char *display;
+ int i;
+
+ /* Open the X11 display */
+ display = NULL; /* Get it from DISPLAY environment variable */
+
+ if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) ||
+ (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) {
+ local_X11 = 1;
+ } else {
+ local_X11 = 0;
+ }
+ SDL_Display = XOpenDisplay(display);
+#if defined(__osf__) && defined(SDL_VIDEO_DRIVER_X11_DYNAMIC)
+ /* On Tru64 if linking without -lX11, it fails and you get following message.
+ * Xlib: connection to ":0.0" refused by server
+ * Xlib: XDM authorization key matches an existing client!
+ *
+ * It succeeds if retrying 1 second later
+ * or if running xhost +localhost on shell.
+ *
+ */
+ if ( SDL_Display == NULL ) {
+ SDL_Delay(1000);
+ SDL_Display = XOpenDisplay(display);
+ }
+#endif
+ if ( SDL_Display == NULL ) {
+ SDL_SetError("Couldn't open X11 display");
+ return(-1);
+ }
+#ifdef X11_DEBUG
+ XSynchronize(SDL_Display, True);
+#endif
+
+ /* Create an alternate X display for graphics updates -- allows us
+ to do graphics updates in a separate thread from event handling.
+ Thread-safe X11 doesn't seem to exist.
+ */
+ GFX_Display = XOpenDisplay(display);
+ if ( GFX_Display == NULL ) {
+ XCloseDisplay(SDL_Display);
+ SDL_Display = NULL;
+ SDL_SetError("Couldn't open X11 display");
+ return(-1);
+ }
+
+ /* Set the normal X error handler */
+ X_handler = XSetErrorHandler(x_errhandler);
+
+ /* Set the error handler if we lose the X display */
+ XIO_handler = XSetIOErrorHandler(xio_errhandler);
+
+ /* Set the X extension error handler */
+ Xext_handler = XSetExtensionErrorHandler(xext_errhandler);
+
+ /* use default screen (from $DISPLAY) */
+ SDL_Screen = DefaultScreen(SDL_Display);
+
+#ifndef NO_SHARED_MEMORY
+ /* Check for MIT shared memory extension */
+ use_mitshm = 0;
+ if ( local_X11 ) {
+ use_mitshm = XShmQueryExtension(SDL_Display);
+ }
+#endif /* NO_SHARED_MEMORY */
+
+ /* Get the available video modes */
+ if(X11_GetVideoModes(this) < 0) {
+ XCloseDisplay(GFX_Display);
+ GFX_Display = NULL;
+ XCloseDisplay(SDL_Display);
+ SDL_Display = NULL;
+ return -1;
+ }
+
+ /* Determine the current screen size */
+ this->info.current_w = DisplayWidth(SDL_Display, SDL_Screen);
+ this->info.current_h = DisplayHeight(SDL_Display, SDL_Screen);
+
+ /* Determine the default screen depth:
+ Use the default visual (or at least one with the same depth) */
+ SDL_DisplayColormap = DefaultColormap(SDL_Display, SDL_Screen);
+ for(i = 0; i < this->hidden->nvisuals; i++)
+ if(this->hidden->visuals[i].depth == DefaultDepth(SDL_Display,
+ SDL_Screen))
+ break;
+ if(i == this->hidden->nvisuals) {
+ /* default visual was useless, take the deepest one instead */
+ i = 0;
+ }
+ SDL_Visual = this->hidden->visuals[i].visual;
+ if ( SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen) ) {
+ SDL_XColorMap = SDL_DisplayColormap;
+ } else {
+ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+ SDL_Visual, AllocNone);
+ }
+ this->hidden->depth = this->hidden->visuals[i].depth;
+ vformat->BitsPerPixel = this->hidden->visuals[i].bpp;
+ if ( vformat->BitsPerPixel > 8 ) {
+ vformat->Rmask = SDL_Visual->red_mask;
+ vformat->Gmask = SDL_Visual->green_mask;
+ vformat->Bmask = SDL_Visual->blue_mask;
+ }
+ if ( this->hidden->depth == 32 ) {
+ vformat->Amask = (0xFFFFFFFF & ~(vformat->Rmask|vformat->Gmask|vformat->Bmask));
+ }
+ X11_SaveVidModeGamma(this);
+
+ /* Allow environment override of screensaver disable. */
+ env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
+ if ( env ) {
+ allow_screensaver = SDL_atoi(env);
+ } else {
+#ifdef SDL_VIDEO_DISABLE_SCREENSAVER
+ allow_screensaver = 0;
+#else
+ allow_screensaver = 1;
+#endif
+ }
+
+ /* See if we have been passed a window to use */
+ SDL_windowid = SDL_getenv("SDL_WINDOWID");
+
+ /* Create the fullscreen and managed windows */
+ create_aux_windows(this);
+
+ /* Create the blank cursor */
+ SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
+ BLANK_CWIDTH, BLANK_CHEIGHT,
+ BLANK_CHOTX, BLANK_CHOTY);
+
+ /* Fill in some window manager capabilities */
+ this->info.wm_available = 1;
+
+ /* We're done! */
+ XFlush(SDL_Display);
+ return(0);
+}
+
+static void X11_DestroyWindow(_THIS, SDL_Surface *screen)
+{
+ /* Clean up OpenGL */
+ if ( screen ) {
+ screen->flags &= ~(SDL_OPENGL|SDL_OPENGLBLIT);
+ }
+ X11_GL_Shutdown(this);
+
+ if ( ! SDL_windowid ) {
+ /* Hide the managed window */
+ if ( WMwindow ) {
+ XUnmapWindow(SDL_Display, WMwindow);
+ }
+ if ( screen && (screen->flags & SDL_FULLSCREEN) ) {
+ screen->flags &= ~SDL_FULLSCREEN;
+ X11_LeaveFullScreen(this);
+ }
+
+ /* Destroy the output window */
+ if ( SDL_Window ) {
+ XDestroyWindow(SDL_Display, SDL_Window);
+ }
+
+ /* Free the colormap entries */
+ if ( SDL_XPixels ) {
+ int numcolors;
+ unsigned long pixel;
+ numcolors = SDL_Visual->map_entries;
+ for ( pixel=0; pixel<numcolors; ++pixel ) {
+ while ( SDL_XPixels[pixel] > 0 ) {
+ XFreeColors(GFX_Display,
+ SDL_DisplayColormap,&pixel,1,0);
+ --SDL_XPixels[pixel];
+ }
+ }
+ SDL_free(SDL_XPixels);
+ SDL_XPixels = NULL;
+ }
+
+ /* Free the graphics context */
+ if ( SDL_GC ) {
+ XFreeGC(SDL_Display, SDL_GC);
+ SDL_GC = 0;
+ }
+ }
+}
+
+static SDL_bool X11_WindowPosition(_THIS, int *x, int *y, int w, int h)
+{
+ const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
+ const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
+ if ( window ) {
+ if ( SDL_sscanf(window, "%d,%d", x, y) == 2 ) {
+ return SDL_TRUE;
+ }
+ if ( SDL_strcmp(window, "center") == 0 ) {
+ center = window;
+ }
+ }
+ if ( center ) {
+ *x = (DisplayWidth(SDL_Display, SDL_Screen) - w)/2;
+ *y = (DisplayHeight(SDL_Display, SDL_Screen) - h)/2;
+ return SDL_TRUE;
+ }
+ return SDL_FALSE;
+}
+
+static void X11_SetSizeHints(_THIS, int w, int h, Uint32 flags)
+{
+ XSizeHints *hints;
+
+ hints = XAllocSizeHints();
+ if ( hints ) {
+ if (!(flags & SDL_RESIZABLE)) {
+ hints->min_width = hints->max_width = w;
+ hints->min_height = hints->max_height = h;
+ hints->flags = PMaxSize | PMinSize;
+ }
+ if ( flags & SDL_FULLSCREEN ) {
+ hints->x = 0;
+ hints->y = 0;
+ hints->flags |= USPosition;
+ } else
+ /* Center it, if desired */
+ if ( X11_WindowPosition(this, &hints->x, &hints->y, w, h) ) {
+ hints->flags |= USPosition;
+
+ /* Hints must be set before moving the window, otherwise an
+ unwanted ConfigureNotify event will be issued */
+ XSetWMNormalHints(SDL_Display, WMwindow, hints);
+
+ XMoveWindow(SDL_Display, WMwindow, hints->x, hints->y);
+
+ /* Flush the resize event so we don't catch it later */
+ XSync(SDL_Display, True);
+ }
+ XSetWMNormalHints(SDL_Display, WMwindow, hints);
+ XFree(hints);
+ }
+
+ /* Respect the window caption style */
+ if ( flags & SDL_NOFRAME ) {
+ SDL_bool set;
+ Atom WM_HINTS;
+
+ /* We haven't modified the window manager hints yet */
+ set = SDL_FALSE;
+
+ /* First try to set MWM hints */
+ WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True);
+ if ( WM_HINTS != None ) {
+ /* Hints used by Motif compliant window managers */
+ struct {
+ unsigned long flags;
+ unsigned long functions;
+ unsigned long decorations;
+ long input_mode;
+ unsigned long status;
+ } MWMHints = { (1L << 1), 0, 0, 0, 0 };
+
+ XChangeProperty(SDL_Display, WMwindow,
+ WM_HINTS, WM_HINTS, 32,
+ PropModeReplace,
+ (unsigned char *)&MWMHints,
+ sizeof(MWMHints)/sizeof(long));
+ set = SDL_TRUE;
+ }
+ /* Now try to set KWM hints */
+ WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True);
+ if ( WM_HINTS != None ) {
+ long KWMHints = 0;
+
+ XChangeProperty(SDL_Display, WMwindow,
+ WM_HINTS, WM_HINTS, 32,
+ PropModeReplace,
+ (unsigned char *)&KWMHints,
+ sizeof(KWMHints)/sizeof(long));
+ set = SDL_TRUE;
+ }
+ /* Now try to set GNOME hints */
+ WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True);
+ if ( WM_HINTS != None ) {
+ long GNOMEHints = 0;
+
+ XChangeProperty(SDL_Display, WMwindow,
+ WM_HINTS, WM_HINTS, 32,
+ PropModeReplace,
+ (unsigned char *)&GNOMEHints,
+ sizeof(GNOMEHints)/sizeof(long));
+ set = SDL_TRUE;
+ }
+ /* Finally set the transient hints if necessary */
+ if ( ! set ) {
+ XSetTransientForHint(SDL_Display, WMwindow, SDL_Root);
+ }
+ } else {
+ SDL_bool set;
+ Atom WM_HINTS;
+
+ /* We haven't modified the window manager hints yet */
+ set = SDL_FALSE;
+
+ /* First try to unset MWM hints */
+ WM_HINTS = XInternAtom(SDL_Display, "_MOTIF_WM_HINTS", True);
+ if ( WM_HINTS != None ) {
+ XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
+ set = SDL_TRUE;
+ }
+ /* Now try to unset KWM hints */
+ WM_HINTS = XInternAtom(SDL_Display, "KWM_WIN_DECORATION", True);
+ if ( WM_HINTS != None ) {
+ XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
+ set = SDL_TRUE;
+ }
+ /* Now try to unset GNOME hints */
+ WM_HINTS = XInternAtom(SDL_Display, "_WIN_HINTS", True);
+ if ( WM_HINTS != None ) {
+ XDeleteProperty(SDL_Display, WMwindow, WM_HINTS);
+ set = SDL_TRUE;
+ }
+ /* Finally unset the transient hints if necessary */
+ if ( ! set ) {
+ XDeleteProperty(SDL_Display, WMwindow, XA_WM_TRANSIENT_FOR);
+ }
+ }
+}
+
+static int X11_CreateWindow(_THIS, SDL_Surface *screen,
+ int w, int h, int bpp, Uint32 flags)
+{
+ int i, depth;
+ Visual *vis;
+ int vis_change;
+ Uint32 Amask;
+
+ /* If a window is already present, destroy it and start fresh */
+ if ( SDL_Window ) {
+ X11_DestroyWindow(this, screen);
+ switch_waiting = 0; /* Prevent jump back to now-meaningless state. */
+ }
+
+ /* See if we have been given a window id */
+ if ( SDL_windowid ) {
+ SDL_Window = SDL_strtol(SDL_windowid, NULL, 0);
+ } else {
+ SDL_Window = 0;
+ }
+
+ /* find out which visual we are going to use */
+ if ( flags & SDL_OPENGL ) {
+ XVisualInfo *vi;
+
+ vi = X11_GL_GetVisual(this);
+ if( !vi ) {
+ return -1;
+ }
+ vis = vi->visual;
+ depth = vi->depth;
+ } else if ( SDL_windowid ) {
+ XWindowAttributes a;
+
+ XGetWindowAttributes(SDL_Display, SDL_Window, &a);
+ vis = a.visual;
+ depth = a.depth;
+ } else {
+ for ( i = 0; i < this->hidden->nvisuals; i++ ) {
+ if ( this->hidden->visuals[i].bpp == bpp )
+ break;
+ }
+ if ( i == this->hidden->nvisuals ) {
+ SDL_SetError("No matching visual for requested depth");
+ return -1; /* should never happen */
+ }
+ vis = this->hidden->visuals[i].visual;
+ depth = this->hidden->visuals[i].depth;
+ }
+#ifdef X11_DEBUG
+ printf("Choosing %s visual at %d bpp - %d colormap entries\n", vis->class == PseudoColor ? "PseudoColor" : (vis->class == TrueColor ? "TrueColor" : (vis->class == DirectColor ? "DirectColor" : "Unknown")), depth, vis->map_entries);
+#endif
+ vis_change = (vis != SDL_Visual);
+ SDL_Visual = vis;
+ this->hidden->depth = depth;
+
+ /* Allocate the new pixel format for this video mode */
+ if ( this->hidden->depth == 32 ) {
+ Amask = (0xFFFFFFFF & ~(vis->red_mask|vis->green_mask|vis->blue_mask));
+ } else {
+ Amask = 0;
+ }
+ if ( ! SDL_ReallocFormat(screen, bpp,
+ vis->red_mask, vis->green_mask, vis->blue_mask, Amask) ) {
+ return -1;
+ }
+
+ /* Create the appropriate colormap */
+ if ( SDL_XColorMap != SDL_DisplayColormap ) {
+ XFreeColormap(SDL_Display, SDL_XColorMap);
+ }
+ if ( SDL_Visual->class == PseudoColor ) {
+ int ncolors;
+
+ /* Allocate the pixel flags */
+ ncolors = SDL_Visual->map_entries;
+ SDL_XPixels = SDL_malloc(ncolors * sizeof(int));
+ if(SDL_XPixels == NULL) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ SDL_memset(SDL_XPixels, 0, ncolors * sizeof(*SDL_XPixels));
+
+ /* always allocate a private colormap on non-default visuals */
+ if ( SDL_Visual != DefaultVisual(SDL_Display, SDL_Screen) ) {
+ flags |= SDL_HWPALETTE;
+ }
+ if ( flags & SDL_HWPALETTE ) {
+ screen->flags |= SDL_HWPALETTE;
+ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+ SDL_Visual, AllocAll);
+ } else {
+ SDL_XColorMap = SDL_DisplayColormap;
+ }
+ } else if ( SDL_Visual->class == DirectColor ) {
+
+ /* Create a colormap which we can manipulate for gamma */
+ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+ SDL_Visual, AllocAll);
+ XSync(SDL_Display, False);
+
+ /* Initialize the colormap to the identity mapping */
+ SDL_GetGammaRamp(0, 0, 0);
+ this->screen = screen;
+ X11_SetGammaRamp(this, this->gamma);
+ this->screen = NULL;
+ } else {
+ /* Create a read-only colormap for our window */
+ SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+ SDL_Visual, AllocNone);
+ }
+
+ /* Recreate the auxiliary windows, if needed (required for GL) */
+ if ( vis_change )
+ create_aux_windows(this);
+
+ if(screen->flags & SDL_HWPALETTE) {
+ /* Since the full-screen window might have got a nonzero background
+ colour (0 is white on some displays), we should reset the
+ background to 0 here since that is what the user expects
+ with a private colormap */
+ XSetWindowBackground(SDL_Display, FSwindow, 0);
+ XClearWindow(SDL_Display, FSwindow);
+ }
+
+ /* resize the (possibly new) window manager window */
+ if( !SDL_windowid ) {
+ X11_SetSizeHints(this, w, h, flags);
+ window_w = w;
+ window_h = h;
+ XResizeWindow(SDL_Display, WMwindow, w, h);
+ }
+
+ /* Create (or use) the X11 display window */
+ if ( !SDL_windowid ) {
+ if ( flags & SDL_OPENGL ) {
+ if ( X11_GL_CreateWindow(this, w, h) < 0 ) {
+ return(-1);
+ }
+ } else {
+ XSetWindowAttributes swa;
+
+ swa.background_pixel = 0;
+ swa.border_pixel = 0;
+ swa.colormap = SDL_XColorMap;
+ SDL_Window = XCreateWindow(SDL_Display, WMwindow,
+ 0, 0, w, h, 0, depth,
+ InputOutput, SDL_Visual,
+ CWBackPixel | CWBorderPixel
+ | CWColormap, &swa);
+ }
+ /* Only manage our input if we own the window */
+ XSelectInput(SDL_Display, SDL_Window,
+ ( EnterWindowMask | LeaveWindowMask
+ | ButtonPressMask | ButtonReleaseMask
+ | PointerMotionMask | ExposureMask ));
+ }
+ /* Create the graphics context here, once we have a window */
+ if ( flags & SDL_OPENGL ) {
+ if ( X11_GL_CreateContext(this) < 0 ) {
+ return(-1);
+ } else {
+ screen->flags |= SDL_OPENGL;
+ }
+ } else {
+ XGCValues gcv;
+
+ gcv.graphics_exposures = False;
+ SDL_GC = XCreateGC(SDL_Display, SDL_Window,
+ GCGraphicsExposures, &gcv);
+ if ( ! SDL_GC ) {
+ SDL_SetError("Couldn't create graphics context");
+ return(-1);
+ }
+ }
+
+ /* Set our colormaps when not setting a GL mode */
+ if ( ! (flags & SDL_OPENGL) ) {
+ XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap);
+ if( !SDL_windowid ) {
+ XSetWindowColormap(SDL_Display, FSwindow, SDL_XColorMap);
+ XSetWindowColormap(SDL_Display, WMwindow, SDL_XColorMap);
+ }
+ }
+
+#if 0 /* This is an experiment - are the graphics faster now? - nope. */
+ if ( SDL_getenv("SDL_VIDEO_X11_BACKINGSTORE") )
+#endif
+ /* Cache the window in the server, when possible */
+ {
+ Screen *xscreen;
+ XSetWindowAttributes a;
+
+ xscreen = ScreenOfDisplay(SDL_Display, SDL_Screen);
+ a.backing_store = DoesBackingStore(xscreen);
+ if ( a.backing_store != NotUseful ) {
+ XChangeWindowAttributes(SDL_Display, SDL_Window,
+ CWBackingStore, &a);
+ }
+ }
+
+ /* Map them both and go fullscreen, if requested */
+ if ( ! SDL_windowid ) {
+ XMapWindow(SDL_Display, SDL_Window);
+ XMapWindow(SDL_Display, WMwindow);
+ X11_WaitMapped(this, WMwindow);
+ if ( flags & SDL_FULLSCREEN ) {
+ screen->flags |= SDL_FULLSCREEN;
+ X11_EnterFullScreen(this);
+ } else {
+ screen->flags &= ~SDL_FULLSCREEN;
+ }
+ }
+
+ return(0);
+}
+
+static int X11_ResizeWindow(_THIS,
+ SDL_Surface *screen, int w, int h, Uint32 flags)
+{
+ if ( ! SDL_windowid ) {
+ /* Resize the window manager window */
+ X11_SetSizeHints(this, w, h, flags);
+ window_w = w;
+ window_h = h;
+ XResizeWindow(SDL_Display, WMwindow, w, h);
+
+ /* Resize the fullscreen and display windows */
+ if ( flags & SDL_FULLSCREEN ) {
+ if ( screen->flags & SDL_FULLSCREEN ) {
+ X11_ResizeFullScreen(this);
+ } else {
+ screen->flags |= SDL_FULLSCREEN;
+ X11_EnterFullScreen(this);
+ }
+ } else {
+ if ( screen->flags & SDL_FULLSCREEN ) {
+ screen->flags &= ~SDL_FULLSCREEN;
+ X11_LeaveFullScreen(this);
+ }
+ }
+ XResizeWindow(SDL_Display, SDL_Window, w, h);
+ }
+ return(0);
+}
+
+SDL_Surface *X11_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ Uint32 saved_flags;
+
+ /* Lock the event thread, in multi-threading environments */
+ SDL_Lock_EventThread();
+
+ /* Check the combination of flags we were passed */
+ if ( flags & SDL_FULLSCREEN ) {
+ /* Clear fullscreen flag if not supported */
+ if ( SDL_windowid ) {
+ flags &= ~SDL_FULLSCREEN;
+ }
+ }
+
+ /* Flush any delayed updates */
+ XSync(GFX_Display, False);
+
+ /* Set up the X11 window */
+ saved_flags = current->flags;
+ if ( (SDL_Window) && ((saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL))
+ && (bpp == current->format->BitsPerPixel)
+ && ((saved_flags&SDL_NOFRAME) == (flags&SDL_NOFRAME)) ) {
+ if (X11_ResizeWindow(this, current, width, height, flags) < 0) {
+ current = NULL;
+ goto done;
+ }
+ X11_PendingConfigureNotifyWidth = width;
+ X11_PendingConfigureNotifyHeight = height;
+ } else {
+ if (X11_CreateWindow(this,current,width,height,bpp,flags) < 0) {
+ current = NULL;
+ goto done;
+ }
+ }
+
+ /* Update the internal keyboard state */
+ X11_SetKeyboardState(SDL_Display, NULL);
+
+ /* When the window is first mapped, ignore non-modifier keys */
+ if ( !current->w && !current->h ) {
+ Uint8 *keys = SDL_GetKeyState(NULL);
+ int i;
+ for ( i = 0; i < SDLK_LAST; ++i ) {
+ switch (i) {
+ case SDLK_NUMLOCK:
+ case SDLK_CAPSLOCK:
+ case SDLK_LCTRL:
+ case SDLK_RCTRL:
+ case SDLK_LSHIFT:
+ case SDLK_RSHIFT:
+ case SDLK_LALT:
+ case SDLK_RALT:
+ case SDLK_LMETA:
+ case SDLK_RMETA:
+ case SDLK_MODE:
+ break;
+ default:
+ keys[i] = SDL_RELEASED;
+ break;
+ }
+ }
+ }
+
+ /* Set up the new mode framebuffer */
+ if ( ((current->w != width) || (current->h != height)) ||
+ ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
+ current->w = width;
+ current->h = height;
+ current->pitch = SDL_CalculatePitch(current);
+ if (X11_ResizeImage(this, current, flags) < 0) {
+ current = NULL;
+ goto done;
+ }
+ }
+
+ /* Clear these flags and set them only if they are in the new set. */
+ current->flags &= ~(SDL_RESIZABLE|SDL_NOFRAME);
+ current->flags |= (flags&(SDL_RESIZABLE|SDL_NOFRAME));
+
+ done:
+ /* Release the event thread */
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+
+ /* We're done! */
+ return(current);
+}
+
+static int X11_ToggleFullScreen(_THIS, int on)
+{
+ Uint32 event_thread;
+
+ /* Don't switch if we don't own the window */
+ if ( SDL_windowid ) {
+ return(0);
+ }
+
+ /* Don't lock if we are the event thread */
+ event_thread = SDL_EventThreadID();
+ if ( event_thread && (SDL_ThreadID() == event_thread) ) {
+ event_thread = 0;
+ }
+ if ( event_thread ) {
+ SDL_Lock_EventThread();
+ }
+ if ( on ) {
+ this->screen->flags |= SDL_FULLSCREEN;
+ X11_EnterFullScreen(this);
+ } else {
+ this->screen->flags &= ~SDL_FULLSCREEN;
+ X11_LeaveFullScreen(this);
+ }
+ X11_RefreshDisplay(this);
+ if ( event_thread ) {
+ SDL_Unlock_EventThread();
+ }
+ SDL_ResetKeyboard();
+ return(1);
+}
+
+/* Update the current mouse state and position */
+static void X11_UpdateMouse(_THIS)
+{
+ Window u1; int u2;
+ Window current_win;
+ int x, y;
+ unsigned int mask;
+
+ /* Lock the event thread, in multi-threading environments */
+ SDL_Lock_EventThread();
+ if ( XQueryPointer(SDL_Display, SDL_Window, &u1, &current_win,
+ &u2, &u2, &x, &y, &mask) ) {
+ if ( (x >= 0) && (x < SDL_VideoSurface->w) &&
+ (y >= 0) && (y < SDL_VideoSurface->h) ) {
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ } else {
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+ }
+ SDL_Unlock_EventThread();
+}
+
+/* simple colour distance metric. Supposed to be better than a plain
+ Euclidian distance anyway. */
+#define COLOUR_FACTOR 3
+#define LIGHT_FACTOR 1
+#define COLOUR_DIST(r1, g1, b1, r2, g2, b2) \
+ (COLOUR_FACTOR * (abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2)) \
+ + LIGHT_FACTOR * abs(r1 + g1 + b1 - (r2 + g2 + b2)))
+
+static void allocate_nearest(_THIS, SDL_Color *colors,
+ SDL_Color *want, int nwant)
+{
+ /*
+ * There is no way to know which ones to choose from, so we retrieve
+ * the entire colormap and try the nearest possible, until we find one
+ * that is shared.
+ */
+ XColor all[256];
+ int i;
+ for(i = 0; i < 256; i++)
+ all[i].pixel = i;
+ /*
+ * XQueryColors sets the flags in the XColor struct, so we use
+ * that to keep track of which colours are available
+ */
+ XQueryColors(GFX_Display, SDL_XColorMap, all, 256);
+
+ for(i = 0; i < nwant; i++) {
+ XColor *c;
+ int j;
+ int best = 0;
+ int mindist = 0x7fffffff;
+ int ri = want[i].r;
+ int gi = want[i].g;
+ int bi = want[i].b;
+ for(j = 0; j < 256; j++) {
+ int rj, gj, bj, d2;
+ if(!all[j].flags)
+ continue; /* unavailable colour cell */
+ rj = all[j].red >> 8;
+ gj = all[j].green >> 8;
+ bj = all[j].blue >> 8;
+ d2 = COLOUR_DIST(ri, gi, bi, rj, gj, bj);
+ if(d2 < mindist) {
+ mindist = d2;
+ best = j;
+ }
+ }
+ if(SDL_XPixels[best])
+ continue; /* already allocated, waste no more time */
+ c = all + best;
+ if(XAllocColor(GFX_Display, SDL_XColorMap, c)) {
+ /* got it */
+ colors[c->pixel].r = c->red >> 8;
+ colors[c->pixel].g = c->green >> 8;
+ colors[c->pixel].b = c->blue >> 8;
+ ++SDL_XPixels[c->pixel];
+ } else {
+ /*
+ * The colour couldn't be allocated, probably being
+ * owned as a r/w cell by another client. Flag it as
+ * unavailable and try again. The termination of the
+ * loop is guaranteed since at least black and white
+ * are always there.
+ */
+ c->flags = 0;
+ i--;
+ }
+ }
+}
+
+int X11_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+ int nrej = 0;
+
+ /* Check to make sure we have a colormap allocated */
+ if ( SDL_XPixels == NULL ) {
+ return(0);
+ }
+ if ( (this->screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) {
+ /* private writable colormap: just set the colours we need */
+ XColor *xcmap;
+ int i;
+ xcmap = SDL_stack_alloc(XColor, ncolors);
+ if(xcmap == NULL)
+ return 0;
+ for ( i=0; i<ncolors; ++i ) {
+ xcmap[i].pixel = i + firstcolor;
+ xcmap[i].red = (colors[i].r<<8)|colors[i].r;
+ xcmap[i].green = (colors[i].g<<8)|colors[i].g;
+ xcmap[i].blue = (colors[i].b<<8)|colors[i].b;
+ xcmap[i].flags = (DoRed|DoGreen|DoBlue);
+ }
+ XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
+ XSync(GFX_Display, False);
+ SDL_stack_free(xcmap);
+ } else {
+ /*
+ * Shared colormap: We only allocate read-only cells, which
+ * increases the likelyhood of colour sharing with other
+ * clients. The pixel values will almost certainly be
+ * different from the requested ones, so the user has to
+ * walk the colormap and see which index got what colour.
+ *
+ * We can work directly with the logical palette since it
+ * has already been set when we get here.
+ */
+ SDL_Color *want, *reject;
+ unsigned long *freelist;
+ int i;
+ int nfree = 0;
+ int nc = this->screen->format->palette->ncolors;
+ colors = this->screen->format->palette->colors;
+ freelist = SDL_stack_alloc(unsigned long, nc);
+ /* make sure multiple allocations of the same cell are freed */
+ for(i = 0; i < ncolors; i++) {
+ int pixel = firstcolor + i;
+ while(SDL_XPixels[pixel]) {
+ freelist[nfree++] = pixel;
+ --SDL_XPixels[pixel];
+ }
+ }
+ XFreeColors(GFX_Display, SDL_XColorMap, freelist, nfree, 0);
+ SDL_stack_free(freelist);
+
+ want = SDL_stack_alloc(SDL_Color, ncolors);
+ reject = SDL_stack_alloc(SDL_Color, ncolors);
+ SDL_memcpy(want, colors + firstcolor, ncolors * sizeof(SDL_Color));
+ /* make sure the user isn't fooled by her own wishes
+ (black is safe, always available in the default colormap) */
+ SDL_memset(colors + firstcolor, 0, ncolors * sizeof(SDL_Color));
+
+ /* now try to allocate the colours */
+ for(i = 0; i < ncolors; i++) {
+ XColor col;
+ col.red = want[i].r << 8;
+ col.green = want[i].g << 8;
+ col.blue = want[i].b << 8;
+ col.flags = DoRed | DoGreen | DoBlue;
+ if(XAllocColor(GFX_Display, SDL_XColorMap, &col)) {
+ /* We got the colour, or at least the nearest
+ the hardware could get. */
+ colors[col.pixel].r = col.red >> 8;
+ colors[col.pixel].g = col.green >> 8;
+ colors[col.pixel].b = col.blue >> 8;
+ ++SDL_XPixels[col.pixel];
+ } else {
+ /*
+ * no more free cells, add it to the list
+ * of rejected colours
+ */
+ reject[nrej++] = want[i];
+ }
+ }
+ if(nrej)
+ allocate_nearest(this, colors, reject, nrej);
+ SDL_stack_free(reject);
+ SDL_stack_free(want);
+ }
+ return nrej == 0;
+}
+
+int X11_SetGammaRamp(_THIS, Uint16 *ramp)
+{
+ int i, ncolors;
+ XColor xcmap[256];
+
+ /* See if actually setting the gamma is supported */
+ if ( SDL_Visual->class != DirectColor ) {
+ SDL_SetError("Gamma correction not supported on this visual");
+ return(-1);
+ }
+
+ /* Calculate the appropriate palette for the given gamma ramp */
+ ncolors = SDL_Visual->map_entries;
+ for ( i=0; i<ncolors; ++i ) {
+ Uint8 c = (256 * i / ncolors);
+ xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c);
+ xcmap[i].red = ramp[0*256+c];
+ xcmap[i].green = ramp[1*256+c];
+ xcmap[i].blue = ramp[2*256+c];
+ xcmap[i].flags = (DoRed|DoGreen|DoBlue);
+ }
+ XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
+ XSync(GFX_Display, False);
+ return(0);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+void X11_VideoQuit(_THIS)
+{
+ /* Shutdown everything that's still up */
+ /* The event thread should be done, so we can touch SDL_Display */
+ if ( SDL_Display != NULL ) {
+ /* Flush any delayed updates */
+ XSync(GFX_Display, False);
+
+ /* Close the connection with the IM server */
+ #ifdef X_HAVE_UTF8_STRING
+ if (SDL_IC != NULL) {
+ XUnsetICFocus(SDL_IC);
+ XDestroyIC(SDL_IC);
+ SDL_IC = NULL;
+ }
+ if (SDL_IM != NULL) {
+ XCloseIM(SDL_IM);
+ SDL_IM = NULL;
+ }
+ #endif
+
+ /* Start shutting down the windows */
+ X11_DestroyImage(this, this->screen);
+ X11_DestroyWindow(this, this->screen);
+ X11_FreeVideoModes(this);
+ if ( SDL_XColorMap != SDL_DisplayColormap ) {
+ XFreeColormap(SDL_Display, SDL_XColorMap);
+ }
+ if ( SDL_iconcolors ) {
+ unsigned long pixel;
+ Colormap dcmap = DefaultColormap(SDL_Display,
+ SDL_Screen);
+ for(pixel = 0; pixel < 256; ++pixel) {
+ while(SDL_iconcolors[pixel] > 0) {
+ XFreeColors(GFX_Display,
+ dcmap, &pixel, 1, 0);
+ --SDL_iconcolors[pixel];
+ }
+ }
+ SDL_free(SDL_iconcolors);
+ SDL_iconcolors = NULL;
+ }
+
+ /* Restore gamma settings if they've changed */
+ if ( SDL_GetAppState() & SDL_APPACTIVE ) {
+ X11_SwapVidModeGamma(this);
+ }
+
+ /* Free that blank cursor */
+ if ( SDL_BlankCursor != NULL ) {
+ this->FreeWMCursor(this, SDL_BlankCursor);
+ SDL_BlankCursor = NULL;
+ }
+
+ /* Close the X11 graphics connection */
+ if ( GFX_Display != NULL ) {
+ XCloseDisplay(GFX_Display);
+ GFX_Display = NULL;
+ }
+
+ /* Close the X11 display connection */
+ XCloseDisplay(SDL_Display);
+ SDL_Display = NULL;
+
+ /* Reset the X11 error handlers */
+ if ( XIO_handler ) {
+ XSetIOErrorHandler(XIO_handler);
+ }
+ if ( X_handler ) {
+ XSetErrorHandler(X_handler);
+ }
+
+ /* Unload GL library after X11 shuts down */
+ X11_GL_UnloadLibrary(this);
+ }
+ if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) {
+ /* Direct screen access, no memory buffer */
+ this->screen->pixels = NULL;
+ }
+
+#if SDL_VIDEO_DRIVER_X11_XME
+ XiGMiscDestroy();
+#endif
+}
+
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h
new file mode 100644
index 0000000..18cf497
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h
@@ -0,0 +1,217 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_x11video_h
+#define _SDL_x11video_h
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_DRIVER_X11_DGAMOUSE
+#include "../Xext/extensions/xf86dga.h"
+#endif
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+#include "../Xext/extensions/Xinerama.h"
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+#include "../Xext/extensions/xf86vmode.h"
+#endif
+#if SDL_VIDEO_DRIVER_X11_XME
+#include "../Xext/extensions/xme.h"
+#endif
+
+#include "SDL_x11dyn.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+/* Private display data */
+struct SDL_PrivateVideoData {
+ int local_X11; /* Flag: true if local display */
+ Display *X11_Display; /* Used for events and window management */
+ Display *GFX_Display; /* Used for graphics and colormap stuff */
+ Visual *SDL_Visual; /* The visual used by our window */
+ Window WMwindow; /* Input window, managed by window manager */
+ Window FSwindow; /* Fullscreen window, completely unmanaged */
+ Window SDL_Window; /* Shared by both displays (no X security?) */
+ Atom WM_DELETE_WINDOW; /* "close-window" protocol atom */
+ WMcursor *BlankCursor; /* The invisible cursor */
+ XIM X11_IM; /* Used to communicate with the input method (IM) server */
+ XIC X11_IC; /* Used for retaining the state, properties, and semantics of communication with the input method (IM) server */
+
+ char *SDL_windowid; /* Flag: true if we have been passed a window */
+
+ /* Direct Graphics Access extension information */
+ int using_dga;
+
+#ifndef NO_SHARED_MEMORY
+ /* MIT shared memory extension information */
+ int use_mitshm;
+ XShmSegmentInfo shminfo;
+#endif
+
+ /* The variables used for displaying graphics */
+ XImage *Ximage; /* The X image for our window */
+ GC gc; /* The graphic context for drawing */
+
+ /* The current width and height of the fullscreen mode */
+ int window_w;
+ int window_h;
+
+ /* Support for internal mouse warping */
+ struct {
+ int x;
+ int y;
+ } mouse_last;
+ struct {
+ int numerator;
+ int denominator;
+ int threshold;
+ } mouse_accel;
+ int mouse_relative;
+
+ /* The current list of available video modes */
+ SDL_Rect **modelist;
+
+ /* available visuals of interest to us, sorted deepest first */
+ struct {
+ Visual *visual;
+ int depth; /* number of significant bits/pixel */
+ int bpp; /* pixel quantum in bits */
+ } visuals[2*5]; /* at most 2 entries for 8, 15, 16, 24, 32 */
+ int nvisuals;
+
+ Visual *vis; /* current visual in use */
+ int depth; /* current visual depth (not bpp) */
+
+ /* Variables used by the X11 video mode code */
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ SDL_NAME(XineramaScreenInfo) xinerama_info;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XRANDR
+ XRRScreenConfiguration* screen_config;
+ int saved_size_id;
+ Rotation saved_rotation;
+#endif
+#if SDL_VIDEO_DRIVER_X11_VIDMODE
+ SDL_NAME(XF86VidModeModeInfo) saved_mode;
+ struct {
+ int x, y;
+ } saved_view;
+#endif
+#if SDL_VIDEO_DRIVER_X11_XME /* XiG XME fullscreen */
+ XiGMiscResolutionInfo saved_res;
+#endif
+
+ int use_xinerama;
+ int use_xrandr;
+ int use_vidmode;
+ int use_xme;
+ int currently_fullscreen;
+
+ /* Automatic mode switching support (entering/leaving fullscreen) */
+ Uint32 switch_waiting;
+ Uint32 switch_time;
+
+ /* Prevent too many XSync() calls */
+ int blit_queued;
+
+ /* Colormap handling */
+ Colormap DisplayColormap; /* The default display colormap */
+ Colormap XColorMap; /* The current window colormap */
+ int *XPixels; /* pixels value allocation counts */
+ float gamma_saved[3]; /* Saved gamma values for VidMode gamma */
+ int gamma_changed; /* flag: has VidMode gamma been modified? */
+
+ short *iconcolors; /* List of colors used by the icon */
+
+ /* Screensaver settings */
+ int allow_screensaver;
+};
+
+extern int X11_wmXAdjust;
+extern int X11_wmYAdjust;
+
+/* Old variable names */
+#define local_X11 (this->hidden->local_X11)
+#define SDL_Display (this->hidden->X11_Display)
+#define GFX_Display (this->hidden->GFX_Display)
+#define SDL_Screen DefaultScreen(this->hidden->X11_Display)
+#define SDL_Visual (this->hidden->vis)
+#define SDL_Root RootWindow(SDL_Display, SDL_Screen)
+#define WMwindow (this->hidden->WMwindow)
+#define FSwindow (this->hidden->FSwindow)
+#define SDL_Window (this->hidden->SDL_Window)
+#define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW)
+#define SDL_BlankCursor (this->hidden->BlankCursor)
+#define SDL_IM (this->hidden->X11_IM)
+#define SDL_IC (this->hidden->X11_IC)
+#define SDL_windowid (this->hidden->SDL_windowid)
+#define using_dga (this->hidden->using_dga)
+#define use_mitshm (this->hidden->use_mitshm)
+#define shminfo (this->hidden->shminfo)
+#define SDL_Ximage (this->hidden->Ximage)
+#define SDL_GC (this->hidden->gc)
+#define window_w (this->hidden->window_w)
+#define window_h (this->hidden->window_h)
+#define mouse_last (this->hidden->mouse_last)
+#define mouse_accel (this->hidden->mouse_accel)
+#define mouse_relative (this->hidden->mouse_relative)
+#define SDL_modelist (this->hidden->modelist)
+#define xinerama_info (this->hidden->xinerama_info)
+#define saved_mode (this->hidden->saved_mode)
+#define saved_view (this->hidden->saved_view)
+#define saved_res (this->hidden->saved_res)
+#define screen_config (this->hidden->screen_config)
+#define saved_size_id (this->hidden->saved_size_id)
+#define saved_rotation (this->hidden->saved_rotation)
+#define use_xinerama (this->hidden->use_xinerama)
+#define use_vidmode (this->hidden->use_vidmode)
+#define use_xrandr (this->hidden->use_xrandr)
+#define use_xme (this->hidden->use_xme)
+#define currently_fullscreen (this->hidden->currently_fullscreen)
+#define switch_waiting (this->hidden->switch_waiting)
+#define switch_time (this->hidden->switch_time)
+#define blit_queued (this->hidden->blit_queued)
+#define SDL_DisplayColormap (this->hidden->DisplayColormap)
+#define SDL_PrivateColormap (this->hidden->PrivateColormap)
+#define SDL_XColorMap (this->hidden->XColorMap)
+#define SDL_XPixels (this->hidden->XPixels)
+#define gamma_saved (this->hidden->gamma_saved)
+#define gamma_changed (this->hidden->gamma_changed)
+#define SDL_iconcolors (this->hidden->iconcolors)
+#define allow_screensaver (this->hidden->allow_screensaver)
+
+/* Some versions of XFree86 have bugs - detect if this is one of them */
+#define BUGGY_XFREE86(condition, buggy_version) \
+((SDL_strcmp(ServerVendor(SDL_Display), "The XFree86 Project, Inc") == 0) && \
+ (VendorRelease(SDL_Display) condition buggy_version))
+
+#endif /* _SDL_x11video_h */
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c
new file mode 100644
index 0000000..2fd59e9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c
@@ -0,0 +1,620 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "SDL_version.h"
+#include "SDL_timer.h"
+#include "SDL_video.h"
+#include "SDL_syswm.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_x11modes_c.h"
+#include "SDL_x11wm_c.h"
+
+static Uint8 reverse_byte(Uint8 x)
+{
+ x = (x & 0xaa) >> 1 | (x & 0x55) << 1;
+ x = (x & 0xcc) >> 2 | (x & 0x33) << 2;
+ x = (x & 0xf0) >> 4 | (x & 0x0f) << 4;
+ return x;
+}
+
+void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
+{
+ SDL_Surface *sicon;
+ XWMHints *wmhints;
+ XImage *icon_image;
+ Pixmap icon_pixmap;
+ Pixmap mask_pixmap;
+ Window icon_window = None;
+ GC gc;
+ XGCValues GCvalues;
+ int i, dbpp;
+ SDL_Rect bounds;
+ Uint8 *LSBmask;
+ Visual *dvis;
+ char *p;
+ int masksize;
+
+ SDL_Lock_EventThread();
+
+ /* The icon must use the default visual, depth and colormap of the
+ screen, so it might need a conversion */
+ dvis = DefaultVisual(SDL_Display, SDL_Screen);
+ dbpp = DefaultDepth(SDL_Display, SDL_Screen);
+ for(i = 0; i < this->hidden->nvisuals; i++) {
+ if(this->hidden->visuals[i].visual == dvis) {
+ dbpp = this->hidden->visuals[i].bpp;
+ break;
+ }
+ }
+
+ /* The Visual struct is supposed to be opaque but we cheat a little */
+ sicon = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
+ dbpp,
+ dvis->red_mask, dvis->green_mask,
+ dvis->blue_mask, 0);
+ if ( sicon == NULL )
+ goto done;
+
+ if(dbpp == 8) {
+ /* Default visual is 8bit; we need to allocate colours from
+ the default colormap */
+ SDL_Color want[256], got[256];
+ int nwant;
+ Colormap dcmap;
+ int missing;
+ dcmap = DefaultColormap(SDL_Display, SDL_Screen);
+ if(icon->format->palette) {
+ /* The icon has a palette as well - we just have to
+ find those colours */
+ nwant = icon->format->palette->ncolors;
+ SDL_memcpy(want, icon->format->palette->colors,
+ nwant * sizeof want[0]);
+ } else {
+ /* try the standard 6x6x6 cube for lack of better
+ ideas */
+ int r, g, b, i;
+ for(r = i = 0; r < 256; r += 0x33)
+ for(g = 0; g < 256; g += 0x33)
+ for(b = 0; b < 256; b += 0x33, i++) {
+ want[i].r = r;
+ want[i].g = g;
+ want[i].b = b;
+ }
+ nwant = 216;
+ }
+ if(SDL_iconcolors) {
+ /* free already allocated colours first */
+ unsigned long freelist[512];
+ int nfree = 0;
+ for(i = 0; i < 256; i++) {
+ while(SDL_iconcolors[i]) {
+ freelist[nfree++] = i;
+ SDL_iconcolors[i]--;
+ }
+ }
+ XFreeColors(GFX_Display, dcmap, freelist, nfree, 0);
+ }
+ if(!SDL_iconcolors)
+ SDL_iconcolors = SDL_malloc(256 * sizeof *SDL_iconcolors);
+ SDL_memset(SDL_iconcolors, 0, 256 * sizeof *SDL_iconcolors);
+
+ /* try to allocate the colours */
+ SDL_memset(got, 0, sizeof got);
+ missing = 0;
+ for(i = 0; i < nwant; i++) {
+ XColor c;
+ c.red = want[i].r << 8;
+ c.green = want[i].g << 8;
+ c.blue = want[i].b << 8;
+ c.flags = DoRed | DoGreen | DoBlue;
+ if(XAllocColor(GFX_Display, dcmap, &c)) {
+ /* got the colour */
+ SDL_iconcolors[c.pixel]++;
+ got[c.pixel] = want[i];
+ } else {
+ missing = 1;
+ }
+ }
+ if(missing) {
+ /* Some colours were apparently missing, so we just
+ allocate all the rest as well */
+ XColor cols[256];
+ for(i = 0; i < 256; i++)
+ cols[i].pixel = i;
+ XQueryColors(GFX_Display, dcmap, cols, 256);
+ for(i = 0; i < 256; i++) {
+ got[i].r = cols[i].red >> 8;
+ got[i].g = cols[i].green >> 8;
+ got[i].b = cols[i].blue >> 8;
+ if(!SDL_iconcolors[i]) {
+ if(XAllocColor(GFX_Display, dcmap,
+ cols + i)) {
+ SDL_iconcolors[i] = 1;
+ } else {
+ /* index not available */
+ got[i].r = 0;
+ got[i].g = 0;
+ got[i].b = 0;
+ }
+ }
+ }
+ }
+
+ SDL_SetColors(sicon, got, 0, 256);
+ }
+
+ bounds.x = 0;
+ bounds.y = 0;
+ bounds.w = icon->w;
+ bounds.h = icon->h;
+ if ( SDL_LowerBlit(icon, &bounds, sicon, &bounds) < 0 )
+ goto done;
+
+ /* We need the mask as given, except in LSBfirst format instead of
+ MSBfirst. Reverse the bits in each byte. */
+ masksize = ((sicon->w + 7) >> 3) * sicon->h;
+ LSBmask = SDL_malloc(masksize);
+ if ( LSBmask == NULL ) {
+ goto done;
+ }
+ SDL_memset(LSBmask, 0, masksize);
+ for(i = 0; i < masksize; i++)
+ LSBmask[i] = reverse_byte(mask[i]);
+ mask_pixmap = XCreatePixmapFromBitmapData(SDL_Display, WMwindow,
+ (char *)LSBmask,
+ sicon->w, sicon->h,
+ 1L, 0L, 1);
+
+ /* Transfer the image to an X11 pixmap */
+ icon_image = XCreateImage(SDL_Display,
+ DefaultVisual(SDL_Display, SDL_Screen),
+ DefaultDepth(SDL_Display, SDL_Screen),
+ ZPixmap, 0, sicon->pixels,
+ sicon->w, sicon->h,
+ 32, 0);
+ icon_image->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+ ? MSBFirst : LSBFirst;
+ icon_pixmap = XCreatePixmap(SDL_Display, SDL_Root, sicon->w, sicon->h,
+ DefaultDepth(SDL_Display, SDL_Screen));
+ gc = XCreateGC(SDL_Display, icon_pixmap, 0, &GCvalues);
+ XPutImage(SDL_Display, icon_pixmap, gc, icon_image,
+ 0, 0, 0, 0, sicon->w, sicon->h);
+ XFreeGC(SDL_Display, gc);
+ XDestroyImage(icon_image);
+ SDL_free(LSBmask);
+ sicon->pixels = NULL;
+
+ /* Some buggy window managers (some versions of Enlightenment, it
+ seems) need an icon window *and* icon pixmap to work properly, while
+ it screws up others. The default is only to use a pixmap. */
+ p = SDL_getenv("SDL_VIDEO_X11_ICONWIN");
+ if(p && *p) {
+ icon_window = XCreateSimpleWindow(SDL_Display, SDL_Root,
+ 0, 0, sicon->w, sicon->h, 0,
+ CopyFromParent,
+ CopyFromParent);
+ XSetWindowBackgroundPixmap(SDL_Display, icon_window,
+ icon_pixmap);
+ XClearWindow(SDL_Display, icon_window);
+ }
+
+ /* Set the window icon to the icon pixmap (and icon window) */
+ wmhints = XAllocWMHints();
+ wmhints->flags = (IconPixmapHint | IconMaskHint | InputHint);
+ wmhints->icon_pixmap = icon_pixmap;
+ wmhints->icon_mask = mask_pixmap;
+ wmhints->input = True;
+ if(icon_window != None) {
+ wmhints->flags |= IconWindowHint;
+ wmhints->icon_window = icon_window;
+ }
+ XSetWMHints(SDL_Display, WMwindow, wmhints);
+ XFree(wmhints);
+ XSync(SDL_Display, False);
+
+ done:
+ SDL_Unlock_EventThread();
+ SDL_FreeSurface(sicon);
+}
+
+void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon)
+{
+ XTextProperty titleprop, iconprop;
+ Status status;
+
+#ifdef X_HAVE_UTF8_STRING
+ Atom _NET_WM_NAME = 0;
+ Atom _NET_WM_ICON_NAME = 0;
+
+ /* Look up some useful Atoms */
+ if (SDL_X11_HAVE_UTF8) {
+ _NET_WM_NAME = XInternAtom(SDL_Display, "_NET_WM_NAME", False);
+ _NET_WM_ICON_NAME = XInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False);
+ }
+#endif
+
+ if ( title != NULL ) {
+ char *title_locale = SDL_iconv_utf8_locale(title);
+ if ( !title_locale ) {
+ SDL_OutOfMemory();
+ return;
+ }
+ status = XStringListToTextProperty(&title_locale, 1, &titleprop);
+ SDL_free(title_locale);
+ if ( status ) {
+ XSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
+ XFree(titleprop.value);
+ }
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ status = Xutf8TextListToTextProperty(SDL_Display,
+ (char **)&title, 1, XUTF8StringStyle, &titleprop);
+ if ( status == Success ) {
+ XSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME);
+ XFree(titleprop.value);
+ }
+ }
+#endif
+ }
+ if ( icon != NULL ) {
+ char *icon_locale = SDL_iconv_utf8_locale(icon);
+ if ( !icon_locale ) {
+ SDL_OutOfMemory();
+ return;
+ }
+ status = XStringListToTextProperty(&icon_locale, 1, &iconprop);
+ SDL_free(icon_locale);
+ if ( status ) {
+ XSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME);
+ XFree(iconprop.value);
+ }
+#ifdef X_HAVE_UTF8_STRING
+ if (SDL_X11_HAVE_UTF8) {
+ status = Xutf8TextListToTextProperty(SDL_Display,
+ (char **)&icon, 1, XUTF8StringStyle, &iconprop);
+ if ( status == Success ) {
+ XSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME);
+ XFree(iconprop.value);
+ }
+ }
+#endif
+ }
+ XSync(SDL_Display, False);
+}
+
+void X11_SetCaption(_THIS, const char *title, const char *icon)
+{
+ SDL_Lock_EventThread();
+ X11_SetCaptionNoLock(this, title, icon);
+ SDL_Unlock_EventThread();
+}
+
+/* Iconify the window */
+int X11_IconifyWindow(_THIS)
+{
+ int result;
+
+ SDL_Lock_EventThread();
+ result = XIconifyWindow(SDL_Display, WMwindow, SDL_Screen);
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+ return(result);
+}
+
+#if 0
+#define D(...) printf(__VA_ARGS__)
+#define E(...) D(__VA_ARGS__)
+#else
+#define D(...) ((void)0)
+#define E(...) ((void)0)
+#endif
+
+static void set_window_pos_nolock(_THIS, int x, int y)
+{
+ int xNew, yNew;
+ Window child;
+ int xAdjust = X11_wmXAdjust;
+ int yAdjust = X11_wmYAdjust;
+
+ /* don't do anything in full-screen mode, because the FSwindow is used
+ * instead of the WMwindow, which will make the adjustment go wild
+ */
+ if (this->screen->flags & SDL_FULLSCREEN)
+ return;
+
+ /* this code is tricky because some window managers, but not all,
+ * will translate the final window position by a given offset
+ * corresponding to the frame decoration.
+ *
+ * so we first try to move the window, get the position that the
+ * window manager has set, and if they are different, re-position the
+ * window again with an adjustment.
+ *
+ * this causes a slight flicker since the window 'jumps' very
+ * quickly from one position to the other.
+ */
+
+ D("%s: move to [%d,%d] adjusted to [%d,%d]\n", __FUNCTION__,
+ x, y, x+xAdjust, y+yAdjust);
+ XMoveWindow(SDL_Display, WMwindow, x + xAdjust, y + yAdjust);
+ XSync(SDL_Display, True);
+ XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, &xNew, &yNew, &child );
+ if (xNew != x || yNew != y) {
+ X11_wmXAdjust = xAdjust = x - xNew;
+ X11_wmYAdjust = yAdjust = y - yNew;
+ D("%s: read pos [%d,%d], recomputing adjust=[%d,%d] moving to [%d,%d]\n",
+ __FUNCTION__, xNew, yNew, xAdjust, yAdjust, x+xAdjust, y+yAdjust);
+ XMoveWindow(SDL_Display, WMwindow, x + xAdjust, y + yAdjust );
+ }
+ XSync(SDL_Display, False);
+}
+
+/* Set window position */
+void X11_SetWindowPos(_THIS, int x, int y)
+{
+ SDL_Lock_EventThread();
+ set_window_pos_nolock(this, x, y);
+ SDL_Unlock_EventThread();
+}
+
+/* Get window position */
+void X11_GetWindowPos(_THIS, int *px, int *py)
+{
+ /* in full-screen mode, you can't move the window */
+ if (this->screen->flags & SDL_FULLSCREEN) {
+ *px = *py = 0;
+ return;
+ }
+
+
+ SDL_Lock_EventThread();
+ {
+ Window child;
+
+ XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, px, py, &child );
+ }
+ SDL_Unlock_EventThread();
+}
+
+static int
+is_window_visible(_THIS, int screen_x, int screen_y, int screen_w, int screen_h )
+{
+ XWindowAttributes attr;
+ int x, y;
+ Window child;
+
+ XGetWindowAttributes( SDL_Display, WMwindow, &attr );
+ XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, &x, &y, &child );
+
+ return ( x >= screen_x && x + attr.width <= screen_x + screen_w &&
+ y >= screen_y && y + attr.height <= screen_y + screen_h );
+}
+
+int X11_IsWindowVisible(_THIS, int recenter)
+{
+ int result = 0;
+ XWindowAttributes attr;
+ int screen_w, screen_h;
+
+ SDL_Lock_EventThread();
+ XGetWindowAttributes( SDL_Display, SDL_Root, &attr );
+ screen_w = attr.width;
+ screen_h = attr.height;
+
+#if SDL_VIDEO_DRIVER_X11_XINERAMA
+ if (use_xinerama) {
+ SDL_NAME(XineramaScreenInfo) *xinerama;
+ int i, screens;
+
+ xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
+ for (i = 0; i < screens; i++) {
+ if ( is_window_visible( this,
+ xinerama[i].x_org, xinerama[i].y_org,
+ xinerama[i].width, xinerama[i].height ) )
+ {
+ result = 1;
+ break;
+ }
+ }
+
+ if ( !result && recenter ) {
+ set_window_pos_nolock(this,
+ xinerama[0].x_org + (xinerama[0].width - this->screen->w)/2,
+ xinerama[0].y_org + (xinerama[0].height - this->screen->h)/2 );
+ }
+ XFree(xinerama);
+ goto Exit;
+ }
+#endif
+ if ( is_window_visible( this, 0, 0, screen_w, screen_h ) ) {
+ result = 1;
+ }
+
+ if ( !result && recenter ) {
+ set_window_pos_nolock( this,
+ (screen_w - this->screen->w)/2,
+ (screen_h - this->screen->h)/2 );
+ }
+#ifdef SDL_VIDEO_DRIVER_X11_XINERAMA
+Exit:
+#endif
+ SDL_Unlock_EventThread();
+ return result;
+}
+
+SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode)
+{
+ int result;
+
+ if ( this->screen == NULL || SDL_Display == NULL ) {
+ return(SDL_GRAB_OFF);
+ }
+ if ( ! SDL_Window ) {
+ return(mode); /* Will be set later on mode switch */
+ }
+ if ( mode == SDL_GRAB_OFF ) {
+ XUngrabPointer(SDL_Display, CurrentTime);
+ XUngrabKeyboard(SDL_Display, CurrentTime);
+ } else {
+ if ( this->screen->flags & SDL_FULLSCREEN ) {
+ /* Unbind the mouse from the fullscreen window */
+ XUngrabPointer(SDL_Display, CurrentTime);
+ }
+ /* Try to grab the mouse */
+#if 0 /* We'll wait here until we actually grab, otherwise behavior undefined */
+ for ( numtries = 0; numtries < 10; ++numtries ) {
+#else
+ for ( ; ; ) {
+#endif
+ result = XGrabPointer(SDL_Display, SDL_Window, True, 0,
+ GrabModeAsync, GrabModeAsync,
+ SDL_Window, None, CurrentTime);
+ if ( result == GrabSuccess ) {
+ break;
+ }
+ SDL_Delay(100);
+ }
+ if ( result != GrabSuccess ) {
+ /* Uh, oh, what do we do here? */ ;
+ }
+ /* Now grab the keyboard */
+ XGrabKeyboard(SDL_Display, WMwindow, True,
+ GrabModeAsync, GrabModeAsync, CurrentTime);
+
+ /* Raise the window if we grab the mouse */
+ if ( !(this->screen->flags & SDL_FULLSCREEN) )
+ XRaiseWindow(SDL_Display, WMwindow);
+
+ /* Make sure we register input focus */
+ SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+ /* Since we grabbed the pointer, we have mouse focus, too. */
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ }
+ XSync(SDL_Display, False);
+
+ return(mode);
+}
+
+SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode)
+{
+ SDL_Lock_EventThread();
+ mode = X11_GrabInputNoLock(this, mode);
+ SDL_Unlock_EventThread();
+
+ return(mode);
+}
+
+#define MM_PER_INCH 25.4
+
+int
+X11_GetMonitorDPI(_THIS, int *px_dpi, int *py_dpi)
+{
+ Display* display = SDL_Display;
+ int screen = XDefaultScreen(display);
+ int xdpi, ydpi;
+
+ int width = XDisplayWidth(display, screen);
+ int width_mm = XDisplayWidthMM(display, screen);
+ int height = XDisplayHeight(display, screen);
+ int height_mm = XDisplayHeightMM(display, screen);
+
+ if (width_mm <= 0 || height_mm <= 0) {
+ return -1;
+ }
+
+ xdpi = (int)(width * MM_PER_INCH / width_mm + 0.5);
+ ydpi = (int)(height * MM_PER_INCH / height_mm + 0.5);
+
+ if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) {
+ return -1;
+ }
+
+ *px_dpi = xdpi;
+ *py_dpi = ydpi;
+
+ return 0;
+}
+
+int
+X11_GetMonitorRect(_THIS, SDL_Rect *rect)
+{
+ Display* display = SDL_Display;
+ int screen = XDefaultScreen(display);
+
+ rect->x = 0;
+ rect->y = 0;
+ rect->w = XDisplayWidth(display, screen);
+ rect->h = XDisplayHeight(display, screen);
+
+ return 0;
+}
+
+/* If 'info' is the right version, this function fills it and returns 1.
+ Otherwise, in case of a version mismatch, it returns -1.
+*/
+static void lock_display(void)
+{
+ SDL_Lock_EventThread();
+}
+static void unlock_display(void)
+{
+ /* Make sure any X11 transactions are completed */
+ SDL_VideoDevice *this = current_video;
+ XSync(SDL_Display, False);
+ SDL_Unlock_EventThread();
+}
+
+#include <stdio.h>
+int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info)
+{
+ if ( info->version.major <= SDL_MAJOR_VERSION ) {
+ info->subsystem = SDL_SYSWM_X11;
+ info->info.x11.display = SDL_Display;
+ info->info.x11.window = SDL_Window;
+ if ( SDL_VERSIONNUM(info->version.major,
+ info->version.minor,
+ info->version.patch) >= 1002 ) {
+ info->info.x11.fswindow = FSwindow;
+ info->info.x11.wmwindow = WMwindow;
+ }
+
+
+ if ( SDL_VERSIONNUM(info->version.major,
+ info->version.minor,
+ info->version.patch) >= 1212 ) {
+ info->info.x11.gfxdisplay = GFX_Display;
+ }
+
+ info->info.x11.lock_func = lock_display;
+ info->info.x11.unlock_func = unlock_display;
+ return(1);
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d\n",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return(-1);
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h
new file mode 100644
index 0000000..c0f938b
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h
@@ -0,0 +1,38 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+#include "SDL_x11video.h"
+
+/* Functions to be exported */
+extern void X11_SetCaptionNoLock(_THIS, const char *title, const char *icon);
+extern void X11_SetCaption(_THIS, const char *title, const char *icon);
+extern void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask);
+extern int X11_IconifyWindow(_THIS);
+extern SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode);
+extern SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode);
+extern int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info);
+extern void X11_GetWindowPos(_THIS, int *px, int *py);
+extern void X11_SetWindowPos(_THIS, int x, int y);
+extern int X11_IsWindowVisible(_THIS, int recenter);
+extern int X11_GetMonitorDPI(_THIS, int* xdpi, int *ydpi);
+extern int X11_GetMonitorRect(_THIS, SDL_Rect *rect);
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv.c
new file mode 100644
index 0000000..62698df
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv.c
@@ -0,0 +1,538 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the XFree86 Xv extension implementation of YUV video overlays */
+
+#if SDL_VIDEO_DRIVER_X11_XV
+
+#include <X11/Xlib.h>
+#ifndef NO_SHARED_MEMORY
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#endif
+#include "../Xext/extensions/Xvlib.h"
+
+#include "SDL_x11yuv_c.h"
+#include "../SDL_yuvfuncs.h"
+
+#define XFREE86_REFRESH_HACK
+#ifdef XFREE86_REFRESH_HACK
+#include "SDL_x11image_c.h"
+#endif
+
+/* Workaround when pitch != width */
+#define PITCH_WORKAROUND
+
+/* Workaround intel i810 video overlay waiting with failing until the
+ first Xv[Shm]PutImage call <sigh> */
+#define INTEL_XV_BADALLOC_WORKAROUND
+
+/* Fix for the NVidia GeForce 2 - use the last available adaptor */
+/*#define USE_LAST_ADAPTOR*/ /* Apparently the NVidia drivers are fixed */
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs x11_yuvfuncs = {
+ X11_LockYUVOverlay,
+ X11_UnlockYUVOverlay,
+ X11_DisplayYUVOverlay,
+ X11_FreeYUVOverlay
+};
+
+struct private_yuvhwdata {
+ int port;
+#ifndef NO_SHARED_MEMORY
+ int yuv_use_mitshm;
+ XShmSegmentInfo yuvshm;
+#endif
+ SDL_NAME(XvImage) *image;
+};
+
+
+static int (*X_handler)(Display *, XErrorEvent *) = NULL;
+
+#ifndef NO_SHARED_MEMORY
+/* Shared memory error handler routine */
+static int shm_error;
+static int shm_errhandler(Display *d, XErrorEvent *e)
+{
+ if ( e->error_code == BadAccess ) {
+ shm_error = True;
+ return(0);
+ } else
+ return(X_handler(d,e));
+}
+#endif /* !NO_SHARED_MEMORY */
+
+static int xv_error;
+static int xv_errhandler(Display *d, XErrorEvent *e)
+{
+ if ( e->error_code == BadMatch ) {
+ xv_error = True;
+ return(0);
+ } else
+ return(X_handler(d,e));
+}
+
+#ifdef INTEL_XV_BADALLOC_WORKAROUND
+static int intel_errhandler(Display *d, XErrorEvent *e)
+{
+ if ( e->error_code == BadAlloc ) {
+ xv_error = True;
+ return(0);
+ } else
+ return(X_handler(d,e));
+}
+
+static void X11_ClearYUVOverlay(SDL_Overlay *overlay)
+{
+ int x,y;
+
+ switch (overlay->format)
+ {
+ case SDL_YV12_OVERLAY:
+ case SDL_IYUV_OVERLAY:
+ for (y = 0; y < overlay->h; y++)
+ memset(overlay->pixels[0] + y * overlay->pitches[0],
+ 0, overlay->w);
+
+ for (y = 0; y < (overlay->h / 2); y++)
+ {
+ memset(overlay->pixels[1] + y * overlay->pitches[1],
+ -128, overlay->w / 2);
+ memset(overlay->pixels[2] + y * overlay->pitches[2],
+ -128, overlay->w / 2);
+ }
+ break;
+ case SDL_YUY2_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ for (y = 0; y < overlay->h; y++)
+ {
+ for (x = 0; x < overlay->w; x += 2)
+ {
+ Uint8 *pixel_pair = overlay->pixels[0] +
+ y * overlay->pitches[0] + x * 2;
+ pixel_pair[0] = 0;
+ pixel_pair[1] = -128;
+ pixel_pair[2] = 0;
+ pixel_pair[3] = -128;
+ }
+ }
+ break;
+ case SDL_UYVY_OVERLAY:
+ for (y = 0; y < overlay->h; y++)
+ {
+ for (x = 0; x < overlay->w; x += 2)
+ {
+ Uint8 *pixel_pair = overlay->pixels[0] +
+ y * overlay->pitches[0] + x * 2;
+ pixel_pair[0] = -128;
+ pixel_pair[1] = 0;
+ pixel_pair[2] = -128;
+ pixel_pair[3] = 0;
+ }
+ }
+ break;
+ }
+}
+#endif
+
+SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+ SDL_Overlay *overlay;
+ struct private_yuvhwdata *hwdata;
+ int xv_port;
+ unsigned int i, j, k;
+ unsigned int adaptors;
+ SDL_NAME(XvAdaptorInfo) *ainfo;
+ int bpp;
+#ifndef NO_SHARED_MEMORY
+ XShmSegmentInfo *yuvshm;
+#endif
+#ifdef INTEL_XV_BADALLOC_WORKAROUND
+ int intel_adapter = False;
+#endif
+
+ /* Look for the XVideo extension with a valid port for this format */
+ xv_port = -1;
+ if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) &&
+ (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display,
+ RootWindow(GFX_Display, SDL_Screen),
+ &adaptors, &ainfo)) ) {
+#ifdef USE_LAST_ADAPTOR
+ for ( i=0; i < adaptors; ++i )
+#else
+ for ( i=0; (i < adaptors) && (xv_port == -1); ++i )
+#endif /* USE_LAST_ADAPTOR */
+ {
+ /* Check to see if the visual can be used */
+ if ( BUGGY_XFREE86(<=, 4001) ) {
+ int visual_ok = 0;
+ for ( j=0; j<ainfo[i].num_formats; ++j ) {
+ if ( ainfo[i].formats[j].visual_id ==
+ SDL_Visual->visualid ) {
+ visual_ok = 1;
+ break;
+ }
+ }
+ if ( ! visual_ok ) {
+ continue;
+ }
+ }
+#ifdef INTEL_XV_BADALLOC_WORKAROUND
+ if ( !strcmp(ainfo[i].name, "Intel(R) Video Overla"))
+ intel_adapter = True;
+ else
+ intel_adapter = False;
+#endif
+ if ( (ainfo[i].type & XvInputMask) &&
+ (ainfo[i].type & XvImageMask) ) {
+ int num_formats;
+ SDL_NAME(XvImageFormatValues) *formats;
+ formats = SDL_NAME(XvListImageFormats)(GFX_Display,
+ ainfo[i].base_id, &num_formats);
+#ifdef USE_LAST_ADAPTOR
+ for ( j=0; j < num_formats; ++j )
+#else
+ for ( j=0; (j < num_formats) && (xv_port == -1); ++j )
+#endif /* USE_LAST_ADAPTOR */
+ {
+ if ( (Uint32)formats[j].id == format ) {
+ for ( k=0; k < ainfo[i].num_ports; ++k ) {
+ if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) {
+ xv_port = ainfo[i].base_id+k;
+ break;
+ }
+ }
+ }
+ }
+ if ( formats ) {
+ XFree(formats);
+ }
+ }
+ }
+ SDL_NAME(XvFreeAdaptorInfo)(ainfo);
+ }
+
+ /* Precalculate the bpp for the pitch workaround below */
+ switch (format) {
+ /* Add any other cases we need to support... */
+ case SDL_YUY2_OVERLAY:
+ case SDL_UYVY_OVERLAY:
+ case SDL_YVYU_OVERLAY:
+ bpp = 2;
+ break;
+ default:
+ bpp = 1;
+ break;
+ }
+
+#if 0
+ /*
+ * !!! FIXME:
+ * "Here are some diffs for X11 and yuv. Note that the last part 2nd
+ * diff should probably be a new call to XvQueryAdaptorFree with ainfo
+ * and the number of adaptors, instead of the loop through like I did."
+ *
+ * ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this
+ * for you, so we end up with a double-free. I need to look at this
+ * more closely... --ryan.
+ */
+ for ( i=0; i < adaptors; ++i ) {
+ if (ainfo[i].name != NULL) Xfree(ainfo[i].name);
+ if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats);
+ }
+ Xfree(ainfo);
+#endif
+
+ if ( xv_port == -1 ) {
+ SDL_SetError("No available video ports for requested format");
+ return(NULL);
+ }
+
+ /* Enable auto-painting of the overlay colorkey */
+ {
+ static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" };
+ unsigned int i;
+
+ SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True);
+ X_handler = XSetErrorHandler(xv_errhandler);
+ for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) {
+ Atom a;
+
+ xv_error = False;
+ a = XInternAtom(GFX_Display, attr[i], True);
+ if ( a != None ) {
+ SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1);
+ XSync(GFX_Display, True);
+ if ( ! xv_error ) {
+ break;
+ }
+ }
+ }
+ XSetErrorHandler(X_handler);
+ SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False);
+ }
+
+ /* Create the overlay structure */
+ overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
+ if ( overlay == NULL ) {
+ SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
+ SDL_OutOfMemory();
+ return(NULL);
+ }
+ SDL_memset(overlay, 0, (sizeof *overlay));
+
+ /* Fill in the basic members */
+ overlay->format = format;
+ overlay->w = width;
+ overlay->h = height;
+
+ /* Set up the YUV surface function structure */
+ overlay->hwfuncs = &x11_yuvfuncs;
+ overlay->hw_overlay = 1;
+
+ /* Create the pixel data and lookup tables */
+ hwdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *hwdata);
+ overlay->hwdata = hwdata;
+ if ( hwdata == NULL ) {
+ SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime);
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ hwdata->port = xv_port;
+#ifndef NO_SHARED_MEMORY
+ yuvshm = &hwdata->yuvshm;
+ SDL_memset(yuvshm, 0, sizeof(*yuvshm));
+ hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
+ 0, width, height, yuvshm);
+#ifdef PITCH_WORKAROUND
+ if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
+ /* Ajust overlay width according to pitch */
+ width = hwdata->image->pitches[0] / bpp;
+ XFree(hwdata->image);
+ hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format,
+ 0, width, height, yuvshm);
+ }
+#endif /* PITCH_WORKAROUND */
+ hwdata->yuv_use_mitshm = (hwdata->image != NULL);
+ if ( hwdata->yuv_use_mitshm ) {
+ yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
+ IPC_CREAT | 0777);
+ if ( yuvshm->shmid >= 0 ) {
+ yuvshm->shmaddr = (char *)shmat(yuvshm->shmid, 0, 0);
+ yuvshm->readOnly = False;
+ if ( yuvshm->shmaddr != (char *)-1 ) {
+ shm_error = False;
+ X_handler = XSetErrorHandler(shm_errhandler);
+ XShmAttach(GFX_Display, yuvshm);
+ XSync(GFX_Display, True);
+ XSetErrorHandler(X_handler);
+ if ( shm_error )
+ shmdt(yuvshm->shmaddr);
+ } else {
+ shm_error = True;
+ }
+ shmctl(yuvshm->shmid, IPC_RMID, NULL);
+ } else {
+ shm_error = True;
+ }
+ if ( shm_error ) {
+ XFree(hwdata->image);
+ hwdata->yuv_use_mitshm = 0;
+ } else {
+ hwdata->image->data = yuvshm->shmaddr;
+ }
+ }
+ if ( !hwdata->yuv_use_mitshm )
+#endif /* NO_SHARED_MEMORY */
+ {
+ hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
+ 0, width, height);
+
+#ifdef PITCH_WORKAROUND
+ if ( hwdata->image != NULL && hwdata->image->pitches[0] != (width*bpp) ) {
+ /* Ajust overlay width according to pitch */
+ XFree(hwdata->image);
+ width = hwdata->image->pitches[0] / bpp;
+ hwdata->image = SDL_NAME(XvCreateImage)(GFX_Display, xv_port, format,
+ 0, width, height);
+ }
+#endif /* PITCH_WORKAROUND */
+ if ( hwdata->image == NULL ) {
+ SDL_SetError("Couldn't create XVideo image");
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ hwdata->image->data = SDL_malloc(hwdata->image->data_size);
+ if ( hwdata->image->data == NULL ) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ }
+
+ /* Find the pitch and offset values for the overlay */
+ overlay->planes = hwdata->image->num_planes;
+ overlay->pitches = (Uint16 *)SDL_malloc(overlay->planes * sizeof(Uint16));
+ overlay->pixels = (Uint8 **)SDL_malloc(overlay->planes * sizeof(Uint8 *));
+ if ( !overlay->pitches || !overlay->pixels ) {
+ SDL_OutOfMemory();
+ SDL_FreeYUVOverlay(overlay);
+ return(NULL);
+ }
+ for ( i=0; i<overlay->planes; ++i ) {
+ overlay->pitches[i] = hwdata->image->pitches[i];
+ overlay->pixels[i] = (Uint8 *)hwdata->image->data +
+ hwdata->image->offsets[i];
+ }
+
+#ifdef XFREE86_REFRESH_HACK
+ /* Work around an XFree86 X server bug (?)
+ We can't perform normal updates in windows that have video
+ being output to them. See SDL_x11image.c for more details.
+ */
+ X11_DisableAutoRefresh(this);
+#endif
+
+#ifdef INTEL_XV_BADALLOC_WORKAROUND
+ /* HACK, GRRR sometimes (i810) creating the overlay succeeds, but the
+ first call to XvShm[Put]Image to a mapped window fails with:
+ "BadAlloc (insufficient resources for operation)". This happens with
+ certain formats when the XvImage is too large to the i810's liking.
+
+ We work around this by doing a test XvShm[Put]Image with a black
+ Xv image, this may cause some flashing, so only do this check if we
+ are running on an intel Xv-adapter. */
+ if (intel_adapter)
+ {
+ xv_error = False;
+ X_handler = XSetErrorHandler(intel_errhandler);
+
+ X11_ClearYUVOverlay(overlay);
+
+ /* We set the destination height and width to 1 pixel to avoid
+ putting a large black rectangle over the screen, thus
+ strongly reducing possible flashing. */
+#ifndef NO_SHARED_MEMORY
+ if ( hwdata->yuv_use_mitshm ) {
+ SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port,
+ SDL_Window, SDL_GC,
+ hwdata->image,
+ 0, 0, overlay->w, overlay->h,
+ 0, 0, 1, 1, False);
+ }
+ else
+#endif
+ {
+ SDL_NAME(XvPutImage)(GFX_Display, hwdata->port,
+ SDL_Window, SDL_GC,
+ hwdata->image,
+ 0, 0, overlay->w, overlay->h,
+ 0, 0, 1, 1);
+ }
+ XSync(GFX_Display, False);
+ XSetErrorHandler(X_handler);
+
+ if (xv_error)
+ {
+ X11_FreeYUVOverlay(this, overlay);
+ return NULL;
+ }
+ /* Repair the (1 pixel worth of) damage we've just done */
+ X11_RefreshDisplay(this);
+ }
+#endif
+
+ /* We're all done.. */
+ return(overlay);
+}
+
+int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ return(0);
+}
+
+void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ return;
+}
+
+int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
+{
+ struct private_yuvhwdata *hwdata;
+
+ hwdata = overlay->hwdata;
+
+#ifndef NO_SHARED_MEMORY
+ if ( hwdata->yuv_use_mitshm ) {
+ SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
+ hwdata->image,
+ src->x, src->y, src->w, src->h,
+ dst->x, dst->y, dst->w, dst->h, False);
+ }
+ else
+#endif
+ {
+ SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
+ hwdata->image,
+ src->x, src->y, src->w, src->h,
+ dst->x, dst->y, dst->w, dst->h);
+ }
+ XSync(GFX_Display, False);
+ return(0);
+}
+
+void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+ struct private_yuvhwdata *hwdata;
+
+ hwdata = overlay->hwdata;
+ if ( hwdata ) {
+ SDL_NAME(XvUngrabPort)(GFX_Display, hwdata->port, CurrentTime);
+#ifndef NO_SHARED_MEMORY
+ if ( hwdata->yuv_use_mitshm ) {
+ XShmDetach(GFX_Display, &hwdata->yuvshm);
+ shmdt(hwdata->yuvshm.shmaddr);
+ }
+#endif
+ if ( hwdata->image ) {
+ XFree(hwdata->image);
+ }
+ SDL_free(hwdata);
+ }
+ if ( overlay->pitches ) {
+ SDL_free(overlay->pitches);
+ overlay->pitches = NULL;
+ }
+ if ( overlay->pixels ) {
+ SDL_free(overlay->pixels);
+ overlay->pixels = NULL;
+ }
+#ifdef XFREE86_REFRESH_HACK
+ X11_EnableAutoRefresh(this);
+#endif
+}
+
+#endif /* SDL_VIDEO_DRIVER_X11_XV */
diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv_c.h
new file mode 100644
index 0000000..d297683
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11yuv_c.h
@@ -0,0 +1,41 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/* This is the XFree86 Xv extension implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_x11video.h"
+
+#if SDL_VIDEO_DRIVER_X11_XV
+
+extern SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst);
+
+extern void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+#endif /* SDL_VIDEO_DRIVER_X11_XV */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.c
new file mode 100644
index 0000000..56bf6ab
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.c
@@ -0,0 +1,1116 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ * Xbios SDL video driver
+ *
+ * Patrice Mandin
+ */
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* Mint includes */
+#include <mint/cookie.h>
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "../ataricommon/SDL_ataric2p_s.h"
+#include "../ataricommon/SDL_atarievents_c.h"
+#include "../ataricommon/SDL_atarimxalloc_c.h"
+#include "../ataricommon/SDL_atarigl_c.h"
+#include "SDL_xbios.h"
+#include "SDL_xbios_blowup.h"
+#include "SDL_xbios_centscreen.h"
+#include "SDL_xbios_sb3.h"
+#include "SDL_xbios_tveille.h"
+#include "SDL_xbios_milan.h"
+
+#define XBIOS_VID_DRIVER_NAME "xbios"
+
+#ifndef C_fVDI
+#define C_fVDI 0x66564449L
+#endif
+
+/* Debug print info */
+#if 0
+#define DEBUG_PRINT(what) \
+ { \
+ printf what; \
+ }
+#define DEBUG_VIDEO_XBIOS 1
+#else
+#define DEBUG_PRINT(what)
+#undef DEBUG_VIDEO_XBIOS
+#endif
+
+/* Initialization/Query functions */
+static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
+static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
+static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
+static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+static void XBIOS_VideoQuit(_THIS);
+
+/* Hardware surface functions */
+static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface);
+static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface);
+static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface);
+static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface);
+static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
+
+#if SDL_VIDEO_OPENGL
+/* OpenGL functions */
+static void XBIOS_GL_SwapBuffers(_THIS);
+#endif
+
+/* To setup palette */
+
+static unsigned short TT_palette[256];
+static unsigned long F30_palette[256];
+
+/* Default list of video modes */
+
+static const xbiosmode_t stmodes[1]={
+ {ST_LOW>>8,320,200,4, XBIOSMODE_C2P}
+};
+
+static const xbiosmode_t ttmodes[2]={
+ {TT_LOW,320,480,8, XBIOSMODE_C2P},
+ {TT_LOW,320,240,8, XBIOSMODE_C2P|XBIOSMODE_DOUBLELINE}
+};
+
+static const xbiosmode_t falconrgbmodes[16]={
+ {BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,0},
+ {BPS16|COL80|OVERSCAN,768,240,16,0},
+ {BPS16|COL80|VERTFLAG,640,400,16,0},
+ {BPS16|COL80,640,200,16,0},
+ {BPS16|OVERSCAN|VERTFLAG,384,480,16,0},
+ {BPS16|OVERSCAN,384,240,16,0},
+ {BPS16|VERTFLAG,320,400,16,0},
+ {BPS16,320,200,16,0},
+ {BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,XBIOSMODE_C2P},
+ {BPS8|COL80|OVERSCAN,768,240,8,XBIOSMODE_C2P},
+ {BPS8|COL80|VERTFLAG,640,400,8,XBIOSMODE_C2P},
+ {BPS8|COL80,640,200,8,XBIOSMODE_C2P},
+ {BPS8|OVERSCAN|VERTFLAG,384,480,8,XBIOSMODE_C2P},
+ {BPS8|OVERSCAN,384,240,8,XBIOSMODE_C2P},
+ {BPS8|VERTFLAG,320,400,8,XBIOSMODE_C2P},
+ {BPS8,320,200,8,XBIOSMODE_C2P}
+};
+
+static const xbiosmode_t falconvgamodes[6]={
+ {BPS16,320,480,16,0},
+ {BPS16|VERTFLAG,320,240,16,0},
+ {BPS8|COL80,640,480,8,XBIOSMODE_C2P},
+ {BPS8|COL80|VERTFLAG,640,240,8,XBIOSMODE_C2P},
+ {BPS8,320,480,8,XBIOSMODE_C2P},
+ {BPS8|VERTFLAG,320,240,8,XBIOSMODE_C2P}
+};
+
+/* Xbios driver bootstrap functions */
+
+static int XBIOS_Available(void)
+{
+ long cookie_vdo, /*cookie_mil,*/ cookie_hade, cookie_scpn;
+ long cookie_fvdi;
+ const char *envr = SDL_getenv("SDL_VIDEODRIVER");
+
+ /* Milan/Hades Atari clones do not have an Atari video chip */
+ if ( /*(Getcookie(C__MIL, &cookie_mil) == C_FOUND) ||*/
+ (Getcookie(C_hade, &cookie_hade) == C_FOUND) ) {
+ return 0;
+ }
+
+ /* fVDI means graphic card, so no Xbios with it */
+ if (Getcookie(C_fVDI, &cookie_fvdi) == C_FOUND) {
+ if (!envr) {
+ return 0;
+ }
+ if (SDL_strcmp(envr, XBIOS_VID_DRIVER_NAME)!=0) {
+ return 0;
+ }
+ /* Except if we force Xbios usage, through env var */
+ }
+
+ /* Cookie _VDO present ? if not, assume ST machine */
+ if (Getcookie(C__VDO, &cookie_vdo) != C_FOUND) {
+ cookie_vdo = VDO_ST << 16;
+ }
+
+ /* Test if we have a monochrome monitor plugged in */
+ switch( cookie_vdo >>16) {
+ case VDO_ST:
+ case VDO_STE:
+ if ( Getrez() == (ST_HIGH>>8) )
+ return 0;
+ break;
+ case VDO_TT:
+ if ( (EgetShift() & ES_MODE) == TT_HIGH)
+ return 0;
+ break;
+ case VDO_F30:
+ if ( VgetMonitor() == MONITOR_MONO)
+ return 0;
+ if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
+ if (!SDL_XBIOS_SB3Usable((scpn_cookie_t *)cookie_scpn)) {
+ return 0;
+ }
+ }
+ break;
+ case VDO_MILAN:
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void XBIOS_DeleteDevice(SDL_VideoDevice *device)
+{
+ SDL_free(device->hidden);
+ SDL_free(device);
+}
+
+static SDL_VideoDevice *XBIOS_CreateDevice(int devindex)
+{
+ SDL_VideoDevice *device;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
+ if ( device ) {
+ SDL_memset(device, 0, (sizeof *device));
+ device->hidden = (struct SDL_PrivateVideoData *)
+ SDL_malloc((sizeof *device->hidden));
+ device->gl_data = (struct SDL_PrivateGLData *)
+ SDL_malloc((sizeof *device->gl_data));
+ }
+ if ( (device == NULL) || (device->hidden == NULL) ) {
+ SDL_OutOfMemory();
+ if ( device ) {
+ SDL_free(device);
+ }
+ return(0);
+ }
+ SDL_memset(device->hidden, 0, (sizeof *device->hidden));
+ SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
+
+ /* Video functions */
+ device->VideoInit = XBIOS_VideoInit;
+ device->ListModes = XBIOS_ListModes;
+ device->SetVideoMode = XBIOS_SetVideoMode;
+ device->SetColors = XBIOS_SetColors;
+ device->UpdateRects = NULL;
+ device->VideoQuit = XBIOS_VideoQuit;
+ device->AllocHWSurface = XBIOS_AllocHWSurface;
+ device->LockHWSurface = XBIOS_LockHWSurface;
+ device->UnlockHWSurface = XBIOS_UnlockHWSurface;
+ device->FlipHWSurface = XBIOS_FlipHWSurface;
+ device->FreeHWSurface = XBIOS_FreeHWSurface;
+
+#if SDL_VIDEO_OPENGL
+ /* OpenGL functions */
+ device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
+ device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
+ device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
+ device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
+ device->GL_SwapBuffers = XBIOS_GL_SwapBuffers;
+#endif
+
+ /* Events */
+ device->InitOSKeymap = Atari_InitOSKeymap;
+ device->PumpEvents = Atari_PumpEvents;
+
+ device->free = XBIOS_DeleteDevice;
+
+ return device;
+}
+
+VideoBootStrap XBIOS_bootstrap = {
+ XBIOS_VID_DRIVER_NAME, "Atari Xbios driver",
+ XBIOS_Available, XBIOS_CreateDevice
+};
+
+void SDL_XBIOS_AddMode(_THIS, int actually_add, const xbiosmode_t *modeinfo)
+{
+ int i = 0;
+
+ switch(modeinfo->depth) {
+ case 15:
+ case 16:
+ i = 1;
+ break;
+ case 24:
+ i = 2;
+ break;
+ case 32:
+ i = 3;
+ break;
+ }
+
+ if ( actually_add ) {
+ SDL_Rect saved_rect[2];
+ xbiosmode_t saved_mode[2];
+ int b, j;
+
+ /* Add the mode, sorted largest to smallest */
+ b = 0;
+ j = 0;
+ while ( (SDL_modelist[i][j]->w > modeinfo->width) ||
+ (SDL_modelist[i][j]->h > modeinfo->height) ) {
+ ++j;
+ }
+ /* Skip modes that are already in our list */
+ if ( (SDL_modelist[i][j]->w == modeinfo->width) &&
+ (SDL_modelist[i][j]->h == modeinfo->height) ) {
+ return;
+ }
+ /* Insert the new mode */
+ saved_rect[b] = *SDL_modelist[i][j];
+ SDL_memcpy(&saved_mode[b], SDL_xbiosmode[i][j], sizeof(xbiosmode_t));
+ SDL_modelist[i][j]->w = modeinfo->width;
+ SDL_modelist[i][j]->h = modeinfo->height;
+ SDL_memcpy(SDL_xbiosmode[i][j], modeinfo, sizeof(xbiosmode_t));
+ /* Everybody scoot down! */
+ if ( saved_rect[b].w && saved_rect[b].h ) {
+ for ( ++j; SDL_modelist[i][j]->w; ++j ) {
+ saved_rect[!b] = *SDL_modelist[i][j];
+ memcpy(&saved_mode[!b], SDL_xbiosmode[i][j], sizeof(xbiosmode_t));
+ *SDL_modelist[i][j] = saved_rect[b];
+ SDL_memcpy(SDL_xbiosmode[i][j], &saved_mode[b], sizeof(xbiosmode_t));
+ b = !b;
+ }
+ *SDL_modelist[i][j] = saved_rect[b];
+ SDL_memcpy(SDL_xbiosmode[i][j], &saved_mode[b], sizeof(xbiosmode_t));
+ }
+ } else {
+ ++SDL_nummodes[i];
+ }
+}
+
+static void XBIOS_ListSTModes(_THIS, int actually_add)
+{
+ SDL_XBIOS_AddMode(this, actually_add, &stmodes[0]);
+}
+
+static void XBIOS_ListTTModes(_THIS, int actually_add)
+{
+ int i;
+
+ for (i=0; i<2; i++) {
+ SDL_XBIOS_AddMode(this, actually_add, &ttmodes[i]);
+ }
+}
+
+static void XBIOS_ListFalconRgbModes(_THIS, int actually_add)
+{
+ int i;
+
+ for (i=0; i<16; i++) {
+ xbiosmode_t modeinfo;
+
+ SDL_memcpy(&modeinfo, &falconrgbmodes[i], sizeof(xbiosmode_t));
+ modeinfo.number &= ~(VGA|PAL);
+ modeinfo.number |= XBIOS_oldvmode & (VGA|PAL);
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+ }
+}
+
+static void XBIOS_ListFalconVgaModes(_THIS, int actually_add)
+{
+ int i;
+
+ for (i=0; i<6; i++) {
+ xbiosmode_t modeinfo;
+
+ SDL_memcpy(&modeinfo, &falconvgamodes[i], sizeof(xbiosmode_t));
+ modeinfo.number &= ~(VGA|PAL);
+ modeinfo.number |= XBIOS_oldvmode & (VGA|PAL);
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+ }
+}
+
+static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
+{
+ int i;
+ long cookie_blow, cookie_scpn, cookie_cnts;
+
+ /* Initialize all variables that we clean on shutdown */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ SDL_nummodes[i] = 0;
+ SDL_modelist[i] = NULL;
+ SDL_xbiosmode[i] = NULL;
+ }
+
+ /* Cookie _VDO present ? if not, assume ST machine */
+ if (Getcookie(C__VDO, &XBIOS_cvdo) != C_FOUND) {
+ XBIOS_cvdo = VDO_ST << 16;
+ }
+
+ /* Allocate memory for old palette */
+ XBIOS_oldpalette = (void *)SDL_malloc(256*sizeof(long));
+ if ( !XBIOS_oldpalette ) {
+ SDL_SetError("Unable to allocate memory for old palette\n");
+ return(-1);
+ }
+
+ /* Initialize video mode list */
+ /* and save current screen status (palette, screen address, video mode) */
+ XBIOS_centscreen = SDL_FALSE;
+ XBIOS_oldvbase = Physbase();
+
+ /* Determine the current screen size */
+ this->info.current_w = 0;
+ this->info.current_h = 0;
+
+ /* Determine the screen depth (use default 8-bit depth) */
+ vformat->BitsPerPixel = 8;
+
+ /* First allocate room for needed video modes */
+ switch (XBIOS_cvdo >>16) {
+ case VDO_ST:
+ case VDO_STE:
+ {
+ short *oldpalette;
+
+ XBIOS_oldvmode=Getrez();
+ switch(XBIOS_oldvmode << 8) {
+ case ST_LOW:
+ XBIOS_oldnumcol=16;
+ break;
+ case ST_MED:
+ XBIOS_oldnumcol=4;
+ break;
+ case ST_HIGH:
+ XBIOS_oldnumcol=2;
+ break;
+ }
+
+ oldpalette= (short *) XBIOS_oldpalette;
+ for (i=0;i<XBIOS_oldnumcol;i++) {
+ *oldpalette++=Setcolor(i,-1);
+ }
+
+ XBIOS_ListSTModes(this, 0);
+ }
+ break;
+ case VDO_TT:
+ XBIOS_oldvmode=EgetShift();
+
+ switch(XBIOS_oldvmode & ES_MODE) {
+ case TT_LOW:
+ XBIOS_oldnumcol=256;
+ break;
+ case ST_LOW:
+ case TT_MED:
+ XBIOS_oldnumcol=16;
+ break;
+ case ST_MED:
+ XBIOS_oldnumcol=4;
+ break;
+ case ST_HIGH:
+ case TT_HIGH:
+ XBIOS_oldnumcol=2;
+ break;
+ }
+ if (XBIOS_oldnumcol) {
+ EgetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+
+ XBIOS_ListTTModes(this, 0);
+ break;
+ case VDO_F30:
+ XBIOS_oldvmode=VsetMode(-1);
+
+ XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS));
+ if (XBIOS_oldnumcol > 256) {
+ XBIOS_oldnumcol = 0;
+ }
+ if (XBIOS_oldnumcol) {
+ VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+
+ vformat->BitsPerPixel = 16;
+
+ /* ScreenBlaster 3 ? */
+ if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
+ SDL_XBIOS_ListSB3Modes(this, 0, (scpn_cookie_t *)cookie_scpn);
+ } else
+ /* Centscreen ? */
+ if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
+ XBIOS_oldvmode = SDL_XBIOS_ListCentscreenModes(this, 0);
+ XBIOS_centscreen = SDL_TRUE;
+ } else
+ /* Standard, with or without Blowup */
+ {
+ switch (VgetMonitor())
+ {
+ case MONITOR_RGB:
+ case MONITOR_TV:
+ XBIOS_ListFalconRgbModes(this, 0);
+ break;
+ case MONITOR_VGA:
+ XBIOS_ListFalconVgaModes(this, 0);
+ break;
+ }
+
+ if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
+ SDL_XBIOS_ListBlowupModes(this, 0, (blow_cookie_t *)cookie_blow);
+ }
+ }
+ break;
+ case VDO_MILAN:
+ {
+ SCREENINFO si;
+
+ /* Read infos about current mode */
+ VsetScreen(-1, &XBIOS_oldvmode, MI_MAGIC, CMD_GETMODE);
+
+ si.size = sizeof(SCREENINFO);
+ si.devID = XBIOS_oldvmode;
+ si.scrFlags = 0;
+ VsetScreen(-1, &si, MI_MAGIC, CMD_GETINFO);
+
+ this->info.current_w = si.scrWidth;
+ this->info.current_h = si.scrHeight;
+
+ XBIOS_oldnumcol = 0;
+ if (si.scrFlags & SCRINFO_OK) {
+ if (si.scrPlanes <= 8) {
+ XBIOS_oldnumcol = 1<<si.scrPlanes;
+ }
+ }
+ if (XBIOS_oldnumcol) {
+ VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+
+ SDL_XBIOS_ListMilanModes(this, 0);
+ }
+ break;
+ }
+
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ int j;
+
+ SDL_xbiosmode[i] = (xbiosmode_t **)
+ SDL_malloc((SDL_nummodes[i]+1)*sizeof(xbiosmode_t *));
+ if ( SDL_xbiosmode[i] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ for ( j=0; j<SDL_nummodes[i]; ++j ) {
+ SDL_xbiosmode[i][j]=(xbiosmode_t *)SDL_malloc(sizeof(xbiosmode_t));
+ if ( SDL_xbiosmode[i][j] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ SDL_memset(SDL_xbiosmode[i][j], 0, sizeof(xbiosmode_t));
+ }
+ SDL_xbiosmode[i][j] = NULL;
+
+ SDL_modelist[i] = (SDL_Rect **)
+ SDL_malloc((SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
+ if ( SDL_modelist[i] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ for ( j=0; j<SDL_nummodes[i]; ++j ) {
+ SDL_modelist[i][j]=(SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
+ if ( SDL_modelist[i][j] == NULL ) {
+ SDL_OutOfMemory();
+ return(-1);
+ }
+ SDL_memset(SDL_modelist[i][j], 0, sizeof(SDL_Rect));
+ }
+ SDL_modelist[i][j] = NULL;
+ }
+
+ /* Now fill the mode list */
+ switch (XBIOS_cvdo >>16) {
+ case VDO_ST:
+ case VDO_STE:
+ XBIOS_ListSTModes(this, 1);
+ break;
+ case VDO_TT:
+ XBIOS_ListTTModes(this, 1);
+ break;
+ case VDO_F30:
+ /* ScreenBlaster 3 ? */
+ if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
+ SDL_XBIOS_ListSB3Modes(this, 1, (scpn_cookie_t *)cookie_scpn);
+ } else
+ /* Centscreen ? */
+ if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
+ XBIOS_oldvmode = SDL_XBIOS_ListCentscreenModes(this, 1);
+ XBIOS_centscreen = SDL_TRUE;
+ } else
+ /* Standard, with or without Blowup */
+ {
+ switch (VgetMonitor())
+ {
+ case MONITOR_RGB:
+ case MONITOR_TV:
+ XBIOS_ListFalconRgbModes(this, 1);
+ break;
+ case MONITOR_VGA:
+ XBIOS_ListFalconVgaModes(this, 1);
+ break;
+ }
+
+ if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
+ SDL_XBIOS_ListBlowupModes(this, 1, (blow_cookie_t *)cookie_blow);
+ }
+ }
+ break;
+ case VDO_MILAN:
+ SDL_XBIOS_ListMilanModes(this, 1);
+ break;
+ }
+
+ XBIOS_screens[0]=NULL;
+ XBIOS_screens[1]=NULL;
+ XBIOS_shadowscreen=NULL;
+
+ /* Update hardware info */
+ this->info.hw_available = 1;
+ this->info.video_mem = (Uint32) Atari_SysMalloc(-1L, MX_STRAM);
+
+ /* Init chunky to planar routine */
+ SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
+
+#if SDL_VIDEO_OPENGL
+ SDL_AtariGL_InitPointers(this);
+#endif
+
+ /* Disable screensavers */
+ if (SDL_XBIOS_TveillePresent(this)) {
+ SDL_XBIOS_TveilleDisable(this);
+ }
+
+ /* We're done! */
+ return(0);
+}
+
+static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
+{
+ return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
+}
+
+static void XBIOS_FreeBuffers(_THIS)
+{
+ int i;
+
+ for (i=0;i<2;i++) {
+ if (XBIOS_screensmem[i]!=NULL) {
+ if ((XBIOS_cvdo>>16) == VDO_MILAN) {
+ if (i==1) {
+ VsetScreen(-1, -1, MI_MAGIC, CMD_FREEPAGE);
+ }
+ } else {
+ Mfree(XBIOS_screensmem[i]);
+ }
+ XBIOS_screensmem[i]=NULL;
+ }
+ }
+
+ if (XBIOS_shadowscreen!=NULL) {
+ Mfree(XBIOS_shadowscreen);
+ XBIOS_shadowscreen=NULL;
+ }
+}
+
+static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
+ int width, int height, int bpp, Uint32 flags)
+{
+ int mode, new_depth;
+ int i, num_buffers;
+ xbiosmode_t *new_video_mode;
+ Uint32 new_screen_size;
+ Uint32 modeflags;
+
+ /* Free current buffers */
+ XBIOS_FreeBuffers(this);
+
+ /* Try to set the requested linear video mode */
+ bpp = (bpp+7)/8-1;
+ for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) {
+ if ( (SDL_modelist[bpp][mode]->w == width) &&
+ (SDL_modelist[bpp][mode]->h == height) ) {
+ break;
+ }
+ }
+ if ( SDL_modelist[bpp][mode] == NULL ) {
+ SDL_SetError("Couldn't find requested mode in list");
+ return(NULL);
+ }
+ new_video_mode = SDL_xbiosmode[bpp][mode];
+
+ modeflags = SDL_FULLSCREEN | SDL_PREALLOC;
+
+ /* Allocate needed buffers: simple/double buffer and shadow surface */
+ new_depth = new_video_mode->depth;
+ if (new_depth == 4) {
+ SDL_Atari_C2pConvert = SDL_Atari_C2pConvert4;
+ new_depth=8;
+ modeflags |= SDL_SWSURFACE|SDL_HWPALETTE;
+ } else if (new_depth == 8) {
+ SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
+ modeflags |= SDL_SWSURFACE|SDL_HWPALETTE;
+ } else {
+ modeflags |= SDL_HWSURFACE;
+ }
+
+ new_screen_size = width * height * ((new_depth)>>3);
+ new_screen_size += 256; /* To align on a 256 byte adress */
+
+ if (new_video_mode->flags & XBIOSMODE_C2P) {
+ XBIOS_shadowscreen = Atari_SysMalloc(new_screen_size, MX_PREFTTRAM);
+
+ if (XBIOS_shadowscreen == NULL) {
+ SDL_SetError("Can not allocate %d KB for shadow buffer", new_screen_size>>10);
+ return (NULL);
+ }
+ SDL_memset(XBIOS_shadowscreen, 0, new_screen_size);
+ }
+
+ /* Output buffer needs to be twice in size for the software double-line mode */
+ if (new_video_mode->flags & XBIOSMODE_DOUBLELINE) {
+ new_screen_size <<= 1;
+ }
+
+ /* Double buffer ? */
+ num_buffers = 1;
+
+#if SDL_VIDEO_OPENGL
+ if (flags & SDL_OPENGL) {
+ if (this->gl_config.double_buffer) {
+ flags |= SDL_DOUBLEBUF;
+ }
+ }
+#endif
+ if ((flags & SDL_DOUBLEBUF) && ((XBIOS_cvdo>>16) != VDO_MILAN)) {
+ num_buffers = 2;
+ modeflags |= SDL_DOUBLEBUF;
+ }
+
+ /* Allocate buffers */
+ for (i=0; i<num_buffers; i++) {
+ if ((XBIOS_cvdo>>16) == VDO_MILAN) {
+ if (i==0) {
+ XBIOS_screensmem[i] = XBIOS_oldvbase;
+ } else {
+ VsetScreen(-1, &XBIOS_screensmem[i], MI_MAGIC, CMD_ALLOCPAGE);
+ }
+ } else {
+ XBIOS_screensmem[i] = Atari_SysMalloc(new_screen_size, MX_STRAM);
+ }
+
+ if (XBIOS_screensmem[i]==NULL) {
+ XBIOS_FreeBuffers(this);
+ SDL_SetError("Can not allocate %d KB for buffer %d", new_screen_size>>10, i);
+ return (NULL);
+ }
+ SDL_memset(XBIOS_screensmem[i], 0, new_screen_size);
+
+ XBIOS_screens[i]=(void *) (( (long) XBIOS_screensmem[i]+256) & 0xFFFFFF00UL);
+ }
+
+ /* Allocate the new pixel format for the screen */
+ if ( ! SDL_ReallocFormat(current, new_depth, 0, 0, 0, 0) ) {
+ XBIOS_FreeBuffers(this);
+ SDL_SetError("Couldn't allocate new pixel format for requested mode");
+ return(NULL);
+ }
+
+ XBIOS_current = new_video_mode;
+ current->w = width;
+ current->h = height;
+ current->pitch = (width * new_depth)>>3;
+
+ /* this is for C2P conversion */
+ XBIOS_pitch = (new_video_mode->width * new_video_mode->depth)>>3;
+
+ if (new_video_mode->flags & XBIOSMODE_C2P)
+ current->pixels = XBIOS_shadowscreen;
+ else
+ current->pixels = XBIOS_screens[0];
+
+ XBIOS_fbnum = 0;
+
+#if SDL_VIDEO_OPENGL
+ if (flags & SDL_OPENGL) {
+ if (!SDL_AtariGL_Init(this, current)) {
+ XBIOS_FreeBuffers(this);
+ SDL_SetError("Can not create OpenGL context");
+ return NULL;
+ }
+
+ modeflags |= SDL_OPENGL;
+ }
+#endif
+
+ current->flags = modeflags;
+
+#ifndef DEBUG_VIDEO_XBIOS
+ /* Now set the video mode */
+ if ((XBIOS_cvdo>>16) == VDO_MILAN) {
+ VsetScreen(-1, XBIOS_screens[0], MI_MAGIC, CMD_SETADR);
+ } else {
+ Setscreen(-1,XBIOS_screens[0],-1);
+ }
+
+ switch(XBIOS_cvdo >> 16) {
+ case VDO_ST:
+ Setscreen(-1,-1,new_video_mode->number);
+
+ /* Reset palette */
+ for (i=0;i<16;i++) {
+ TT_palette[i]= ((i>>1)<<8) | (((i*8)/17)<<4) | (i>>1);
+ }
+ Setpalette(TT_palette);
+ break;
+ case VDO_STE:
+ Setscreen(-1,-1,new_video_mode->number);
+
+ /* Reset palette */
+ for (i=0;i<16;i++)
+ {
+ int c;
+
+ c=((i&1)<<3)|((i>>1)&7);
+ TT_palette[i]=(c<<8)|(c<<4)|c;
+ }
+ Setpalette(TT_palette);
+ break;
+ case VDO_TT:
+ EsetShift(new_video_mode->number);
+ break;
+ case VDO_F30:
+ if (XBIOS_centscreen) {
+ SDL_XBIOS_CentscreenSetmode(this, width, height, new_depth);
+ } else {
+ VsetMode(new_video_mode->number);
+ }
+
+ /* Set hardware palette to black in True Colour */
+ if (new_depth > 8) {
+ SDL_memset(F30_palette, 0, sizeof(F30_palette));
+ VsetRGB(0,256,F30_palette);
+ }
+ break;
+ case VDO_MILAN:
+ VsetScreen(-1, new_video_mode->number, MI_MAGIC, CMD_SETMODE);
+
+ /* Set hardware palette to black in True Colour */
+ if (new_depth > 8) {
+ SDL_memset(F30_palette, 0, sizeof(F30_palette));
+ VsetRGB(0,256,F30_palette);
+ }
+ break;
+ }
+
+ Vsync();
+#endif
+
+ this->UpdateRects = XBIOS_UpdateRects;
+
+ return (current);
+}
+
+/* We don't actually allow hardware surfaces other than the main one */
+static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(-1);
+}
+
+static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return(0);
+}
+
+static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
+{
+ return;
+}
+
+static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
+{
+ SDL_Surface *surface;
+
+ surface = this->screen;
+
+ if (XBIOS_current->flags & XBIOSMODE_C2P) {
+ int i;
+ int doubleline = (XBIOS_current->flags & XBIOSMODE_DOUBLELINE ? 1 : 0);
+
+ for (i=0;i<numrects;i++) {
+ void *source,*destination;
+ int x1,x2;
+
+ x1 = rects[i].x & ~15;
+ x2 = rects[i].x+rects[i].w;
+ if (x2 & 15) {
+ x2 = (x2 | 15) +1;
+ }
+
+ source = surface->pixels;
+ source += surface->pitch * rects[i].y;
+ source += x1;
+
+ destination = XBIOS_screens[XBIOS_fbnum];
+ destination += XBIOS_pitch * rects[i].y;
+ destination += x1;
+
+ /* Convert chunky to planar screen */
+ SDL_Atari_C2pConvert(
+ source,
+ destination,
+ x2-x1,
+ rects[i].h,
+ doubleline,
+ surface->pitch,
+ XBIOS_pitch
+ );
+ }
+ }
+
+#ifndef DEBUG_VIDEO_XBIOS
+ if ((XBIOS_cvdo>>16) == VDO_MILAN) {
+ VsetScreen(-1, XBIOS_screens[XBIOS_fbnum], MI_MAGIC, CMD_SETADR);
+ } else {
+ Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
+ }
+
+ Vsync();
+#endif
+
+ if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
+ XBIOS_fbnum ^= 1;
+ if ((XBIOS_current->flags & XBIOSMODE_C2P) == 0) {
+ surface->pixels=XBIOS_screens[XBIOS_fbnum];
+ }
+ }
+}
+
+static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface)
+{
+ if (XBIOS_current->flags & XBIOSMODE_C2P) {
+ void *destscr;
+ int destx;
+ int doubleline = (XBIOS_current->flags & XBIOSMODE_DOUBLELINE ? 1 : 0);
+
+ /* Center on destination screen */
+ destscr = XBIOS_screens[XBIOS_fbnum];
+ destscr += XBIOS_pitch * ((XBIOS_current->height - surface->h) >> 1);
+ destx = (XBIOS_current->width - surface->w) >> 1;
+ destx &= ~15;
+ destscr += destx;
+
+ /* Convert chunky to planar screen */
+ SDL_Atari_C2pConvert(
+ surface->pixels,
+ destscr,
+ surface->w,
+ surface->h,
+ doubleline,
+ surface->pitch,
+ XBIOS_pitch
+ );
+ }
+
+#ifndef DEBUG_VIDEO_XBIOS
+ if ((XBIOS_cvdo>>16) == VDO_MILAN) {
+ VsetScreen(-1, XBIOS_screens[XBIOS_fbnum], MI_MAGIC, CMD_SETADR);
+ } else {
+ Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
+ }
+
+ Vsync();
+#endif
+
+ if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
+ XBIOS_fbnum ^= 1;
+ if ((XBIOS_current->flags & XBIOSMODE_C2P) == 0) {
+ surface->pixels=XBIOS_screens[XBIOS_fbnum];
+ }
+ }
+
+ return(0);
+}
+
+static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+#ifndef DEBUG_VIDEO_XBIOS
+ int i;
+ int r,v,b;
+
+ switch( XBIOS_cvdo >> 16) {
+ case VDO_ST:
+ case VDO_STE:
+ for (i=0;i<ncolors;i++)
+ {
+ r = colors[i].r;
+ v = colors[i].g;
+ b = colors[i].b;
+
+ TT_palette[firstcolor+i]=((r*30)+(v*59)+(b*11))/100;
+ }
+ SDL_Atari_C2pConvert4_pal(TT_palette); /* convert the lighting */
+ break;
+ case VDO_TT:
+ for(i = 0; i < ncolors; i++)
+ {
+ r = colors[i].r;
+ v = colors[i].g;
+ b = colors[i].b;
+
+ TT_palette[i]=((r>>4)<<8)|((v>>4)<<4)|(b>>4);
+ }
+ EsetPalette(firstcolor,ncolors,TT_palette);
+ break;
+ case VDO_F30:
+ case VDO_MILAN:
+ for(i = 0; i < ncolors; i++)
+ {
+ r = colors[i].r;
+ v = colors[i].g;
+ b = colors[i].b;
+
+ F30_palette[i]=(r<<16)|(v<<8)|b;
+ }
+ VsetRGB(firstcolor,ncolors,F30_palette);
+ break;
+ }
+#endif
+
+ return(1);
+}
+
+/* Note: If we are terminated, this could be called in the middle of
+ another SDL video routine -- notably UpdateRects.
+*/
+static void XBIOS_VideoQuit(_THIS)
+{
+ int i,j;
+
+ Atari_ShutdownEvents();
+
+ /* Restore video mode and palette */
+#ifndef DEBUG_VIDEO_XBIOS
+ switch(XBIOS_cvdo >> 16) {
+ case VDO_ST:
+ case VDO_STE:
+ Setscreen(-1,XBIOS_oldvbase,XBIOS_oldvmode);
+ if (XBIOS_oldnumcol) {
+ Setpalette(XBIOS_oldpalette);
+ }
+ break;
+ case VDO_TT:
+ Setscreen(-1,XBIOS_oldvbase,-1);
+ EsetShift(XBIOS_oldvmode);
+ if (XBIOS_oldnumcol) {
+ EsetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+ break;
+ case VDO_F30:
+ Setscreen(-1, XBIOS_oldvbase, -1);
+ if (XBIOS_centscreen) {
+ SDL_XBIOS_CentscreenRestore(this, XBIOS_oldvmode);
+ } else {
+ VsetMode(XBIOS_oldvmode);
+ }
+ if (XBIOS_oldnumcol) {
+ VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+ break;
+ case VDO_MILAN:
+ VsetScreen(-1, &XBIOS_oldvbase, MI_MAGIC, CMD_SETADR);
+ VsetScreen(-1, &XBIOS_oldvmode, MI_MAGIC, CMD_SETMODE);
+ if (XBIOS_oldnumcol) {
+ VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+ }
+ break;
+ }
+ Vsync();
+#endif
+
+#if SDL_VIDEO_OPENGL
+ if (gl_active) {
+ SDL_AtariGL_Quit(this, SDL_TRUE);
+ }
+#endif
+
+ if (XBIOS_oldpalette) {
+ SDL_free(XBIOS_oldpalette);
+ XBIOS_oldpalette=NULL;
+ }
+ XBIOS_FreeBuffers(this);
+
+ /* Free mode list */
+ for ( i=0; i<NUM_MODELISTS; ++i ) {
+ if ( SDL_modelist[i] != NULL ) {
+ for ( j=0; SDL_modelist[i][j]; ++j )
+ SDL_free(SDL_modelist[i][j]);
+ SDL_free(SDL_modelist[i]);
+ SDL_modelist[i] = NULL;
+ }
+ if ( SDL_xbiosmode[i] != NULL ) {
+ for ( j=0; SDL_xbiosmode[i][j]; ++j )
+ SDL_free(SDL_xbiosmode[i][j]);
+ SDL_free(SDL_xbiosmode[i]);
+ SDL_xbiosmode[i] = NULL;
+ }
+ }
+
+ this->screen->pixels = NULL;
+
+ /* Restore screensavers */
+ if (SDL_XBIOS_TveillePresent(this)) {
+ SDL_XBIOS_TveilleEnable(this);
+ }
+}
+
+#if SDL_VIDEO_OPENGL
+
+static void XBIOS_GL_SwapBuffers(_THIS)
+{
+ SDL_AtariGL_SwapBuffers(this);
+ XBIOS_FlipHWSurface(this, this->screen);
+ SDL_AtariGL_MakeCurrent(this);
+}
+
+#endif
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.h
new file mode 100644
index 0000000..3ad6827
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios.h
@@ -0,0 +1,111 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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_xbios_h
+#define _SDL_xbios_h
+
+#include "SDL_stdinc.h"
+#include "../SDL_sysvideo.h"
+
+/* Hidden "this" pointer for the video functions */
+#define _THIS SDL_VideoDevice *this
+
+#define XBIOSMODE_DOUBLELINE (1<<0)
+#define XBIOSMODE_C2P (1<<1)
+
+typedef struct
+{
+ Uint16 number; /* Video mode number */
+ Uint16 width; /* Size */
+ Uint16 height;
+ Uint16 depth; /* bits per plane */
+ Uint16 flags;
+} xbiosmode_t;
+
+/* Private display data */
+#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
+
+struct SDL_PrivateVideoData {
+ long cookie_vdo;
+ long old_video_mode; /* Old video mode before entering SDL */
+ void *old_video_base; /* Old pointer to screen buffer */
+ void *old_palette; /* Old palette */
+ Uint32 old_num_colors; /* Nb of colors in saved palette */
+
+ void *screens[2]; /* Pointers to aligned screen buffer */
+ void *screensmem[2]; /* Pointers to screen buffer */
+ void *shadowscreen; /* Shadow screen for c2p conversion */
+ int frame_number; /* Number of frame for double buffer */
+ int pitch; /* Destination line width for C2P */
+
+ SDL_bool centscreen; /* Centscreen extension present ? */
+
+ xbiosmode_t *current; /* Current set mode */
+ int SDL_nummodes[NUM_MODELISTS];
+ SDL_Rect **SDL_modelist[NUM_MODELISTS];
+ xbiosmode_t **SDL_xbiosmode[NUM_MODELISTS];
+};
+
+/* _VDO cookie values */
+enum {
+ VDO_ST=0,
+ VDO_STE,
+ VDO_TT,
+ VDO_F30,
+ VDO_MILAN
+};
+
+/* Monitor types */
+enum {
+ MONITOR_MONO=0,
+ MONITOR_TV,
+ MONITOR_VGA,
+ MONITOR_RGB
+};
+
+/* EgetShift masks */
+#define ES_MODE 0x0700
+
+/* Hidden structure -> variables names */
+#define SDL_nummodes (this->hidden->SDL_nummodes)
+#define SDL_modelist (this->hidden->SDL_modelist)
+#define SDL_xbiosmode (this->hidden->SDL_xbiosmode)
+#define XBIOS_mutex (this->hidden->mutex)
+#define XBIOS_cvdo (this->hidden->cookie_vdo)
+#define XBIOS_oldpalette (this->hidden->old_palette)
+#define XBIOS_oldnumcol (this->hidden->old_num_colors)
+#define XBIOS_oldvbase (this->hidden->old_video_base)
+#define XBIOS_oldvmode (this->hidden->old_video_mode)
+#define XBIOS_screens (this->hidden->screens)
+#define XBIOS_screensmem (this->hidden->screensmem)
+#define XBIOS_shadowscreen (this->hidden->shadowscreen)
+#define XBIOS_fbnum (this->hidden->frame_number)
+#define XBIOS_pitch (this->hidden->pitch)
+#define XBIOS_centscreen (this->hidden->centscreen)
+#define XBIOS_current (this->hidden->current)
+
+/*--- Functions prototypes ---*/
+
+void SDL_XBIOS_AddMode(_THIS, int actually_add, const xbiosmode_t *modeinfo);
+
+#endif /* _SDL_xbios_h */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.c
new file mode 100644
index 0000000..2950b84
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.c
@@ -0,0 +1,77 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Blowup extension definitions
+
+ Patrice Mandin
+*/
+
+#include <mint/falcon.h>
+
+#include "SDL_xbios.h"
+#include "SDL_xbios_blowup.h"
+
+void SDL_XBIOS_ListBlowupModes(_THIS, int actually_add, blow_cookie_t *cookie_blow)
+{
+ int i, j, num_mode, bank;
+ blow_mode_t *blow_mode;
+ xbiosmode_t modeinfo;
+
+ if (actually_add) {
+ /* Set bit 15 for old modes */
+ for (i=0;i<NUM_MODELISTS;i++) {
+ if ( SDL_xbiosmode[i] != NULL ) {
+ for ( j=0; SDL_xbiosmode[i][j]; ++j ) {
+ SDL_xbiosmode[i][j]->number |= 1<<15;
+ }
+ }
+ }
+ }
+
+ /* Add Blowup modes for 8 and 16 bpp */
+ for (num_mode=3; num_mode<5; num_mode++) {
+ bank = cookie_blow->num_mode[num_mode];
+ blow_mode = &(cookie_blow->blowup_modes[num_mode+(bank*5)]);
+
+ /* Check extended mode enabled */
+ if (blow_mode->enabled == 0) {
+ /* Check monitor needed for this mode */
+ if ((blow_mode->monitor == cookie_blow->montype)
+ || ((blow_mode->monitor == MONITOR_TV)
+ && (cookie_blow->montype == MONITOR_RGB))
+ || ((blow_mode->monitor == MONITOR_RGB)
+ && (cookie_blow->montype == MONITOR_TV)))
+ {
+ /* we can use this extended mode */
+ modeinfo.number = (num_mode == 3 ? BPS8 : BPS16);
+ modeinfo.width = blow_mode->width + 1;
+ modeinfo.height = blow_mode->height + 1;
+ modeinfo.depth = (num_mode == 3 ? 8 : 16);
+ modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+ }
+ }
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.h
new file mode 100644
index 0000000..09a3651
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_blowup.h
@@ -0,0 +1,86 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Blowup extension definitions
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_xbios_blowup_h
+#define _SDL_xbios_blowup_h
+
+#include "SDL_xbios.h"
+
+/*--- Types ---*/
+
+typedef struct {
+ /* 64 bytes */
+ unsigned short enabled; /* Extended mode enabled ? 0=yes, <>0=no */
+ unsigned short dummy10[6];
+ unsigned short registers_0E; /* value for register 0xffff820e */
+ unsigned short registers_10; /* value for register 0xffff8210 */
+ unsigned short dummy11[23];
+
+ /* 64 bytes */
+ unsigned short width; /* width-1 */
+ unsigned short height; /* height-1 */
+ unsigned short dummy20;
+ unsigned long screensize; /* screensize in bytes */
+ unsigned short dummy21[8];
+ unsigned short virtual; /* Virtual screen ? */
+ unsigned short virwidth; /* Virtual screen width */
+ unsigned short virheight; /* Virtual screen height */
+
+ unsigned short dummy22;
+ unsigned short monitor; /* Monitor defined for this mode */
+ unsigned short extension; /* Extended mode defined ? 0=yes, 1=no */
+ unsigned short dummy23[13];
+
+ /* 64 bytes */
+ unsigned short dummy30;
+ unsigned short registers_82[6]; /* values for registers 0xffff8282-8c */
+ unsigned short dummy31[9];
+
+ unsigned short dummy32;
+ unsigned short registers_A2[6]; /* values for registers 0xffff82a2-ac */
+ unsigned short dummy33[9];
+
+ /* 64 bytes */
+ unsigned short registers_C0; /* value for register 0xffff82c0 */
+ unsigned short registers_C2; /* value for register 0xffff82c2 */
+ unsigned short dummy40[30];
+} blow_mode_t;
+
+typedef struct {
+ blow_mode_t blowup_modes[10];
+ unsigned char num_mode[6];
+ unsigned long dummy;
+ unsigned short montype;
+} blow_cookie_t;
+
+/*--- Functions prototypes ---*/
+
+void SDL_XBIOS_ListBlowupModes(_THIS, int actually_add, blow_cookie_t *cookie_blow);
+
+#endif /* _SDL_xbios_blowup_h */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.c
new file mode 100644
index 0000000..6daade2
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.c
@@ -0,0 +1,104 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Centscreen extension definitions
+
+ Patrice Mandin
+*/
+
+#include <mint/falcon.h>
+
+#include "SDL_xbios.h"
+#include "SDL_xbios_centscreen.h"
+
+int SDL_XBIOS_ListCentscreenModes(_THIS, int actually_add)
+{
+ centscreen_mode_t curmode, listedmode;
+ unsigned long result;
+ int cur_handle; /* Current Centscreen mode handle */
+
+ /* Add Centscreen modes */
+ Vread(&curmode);
+ cur_handle = curmode.handle;
+ curmode.mode = curmode.physx = curmode.physy = curmode.plan =
+ curmode.logx = curmode.logy = -1;
+
+ result = Vfirst(&curmode, &listedmode);
+ if (result==0) {
+ while (result==0) {
+ /* Don't add modes with virtual screen */
+ if ((listedmode.mode & CSCREEN_VIRTUAL)==0) {
+ /* Don't add modes with bpp<8 */
+ if (listedmode.plan>=8) {
+ xbiosmode_t modeinfo;
+
+ modeinfo.number = listedmode.mode;
+ modeinfo.width = listedmode.physx;
+ modeinfo.height = listedmode.physy;
+ modeinfo.depth = listedmode.plan;
+ modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+ }
+ }
+ SDL_memcpy(&curmode, &listedmode, sizeof(centscreen_mode_t));
+ curmode.mode = curmode.physx = curmode.physy = curmode.plan =
+ curmode.logx = curmode.logy = -1;
+ result = Vnext(&curmode, &listedmode);
+ }
+ } else {
+ fprintf(stderr, "No suitable Centscreen modes\n");
+ }
+
+ return cur_handle;
+}
+
+void SDL_XBIOS_CentscreenSetmode(_THIS, int width, int height, int planes)
+{
+ centscreen_mode_t newmode, curmode;
+
+ newmode.handle = newmode.mode = newmode.logx = newmode.logy = -1;
+ newmode.physx = width;
+ newmode.physy = height;
+ newmode.plan = planes;
+ Vwrite(0, &newmode, &curmode);
+
+#ifdef SDL_VIDEO_DISABLE_SCREENSAVER
+ /* Disable screensaver */
+ Vread(&newmode);
+ newmode.mode &= ~(CSCREEN_SAVER|CSCREEN_ENERGYSTAR);
+ Vwrite(0, &newmode, &curmode);
+#endif /* SDL_VIDEO_DISABLE_SCREENSAVER */
+}
+
+void SDL_XBIOS_CentscreenRestore(_THIS, int prev_handle)
+{
+ centscreen_mode_t newmode, curmode;
+
+ /* Restore old video mode */
+ newmode.handle = prev_handle;
+ newmode.mode = newmode.physx = newmode.physy = newmode.plan =
+ newmode.logx = newmode.logy = -1;
+ Vwrite(0, &newmode, &curmode);
+}
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.h
new file mode 100644
index 0000000..dfe88d9
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_centscreen.h
@@ -0,0 +1,114 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Centscreen extension definitions
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_xbios_centscreen_h
+#define _SDL_xbios_centscreen_h
+
+#include <mint/falcon.h> /* for trap_14_xxx macros */
+
+#include "SDL_xbios.h"
+
+/*--- Defines ---*/
+
+#define CSCREEN_ENERGYSTAR (1<<9)
+#define CSCREEN_SAVER (1<<10)
+#define CSCREEN_VIRTUAL (1<<11)
+#define CSCREEN_EXTCLOCK_CT2 (1<<12)
+#define CSCREEN_EXTCLOCK (1<<13)
+#define CSCREEN_STANDARD (1<<14)
+#define CSCREEN_DEFAULT (1<<15)
+
+/*--- Structures ---*/
+
+typedef struct {
+ unsigned short handle; /* videomode handle */
+ unsigned short mode; /* Falcon videomode code */
+ unsigned short physx; /* visible width */
+ unsigned short physy; /* visible height */
+ unsigned short plan; /* bitplanes */
+ unsigned short logx; /* virtual width */
+ unsigned short logy; /* virtual height */
+ unsigned short eco; /* screen saver delay */
+ unsigned short eco2; /* energy star screen saver delay */
+ unsigned short wsize; /* screen width (mm) */
+ unsigned short hsize; /* screen height (mm) */
+ unsigned short dummy[21];
+ unsigned char name[32]; /* videomode name */
+} centscreen_mode_t;
+
+/*--- Functions prototypes ---*/
+
+#define Vread(current_mode) \
+ (void)trap_14_wl((short)0x41,(long)(current_mode))
+#define Vwrite(init_vdi, inparam, outparam) \
+ (long)trap_14_wwll((short)0x42,(short)(init_vdi),(long)(inparam),(long)(outparam))
+#define Vattrib(inparam, outparam) \
+ (void)trap_14_wll((short)0x43,(long)(inparam),(long)(outparam))
+#define Vcreate(inparam, outparam) \
+ (void)trap_14_wll((short)0x44,(long)(inparam),(long)(outparam))
+#define Vdelete(handle) \
+ (long)trap_14_ww((short)0x45,(short)(handle))
+#define Vfirst(mask,mode) \
+ (long)trap_14_wll((short)0x46,(long)(mask),(long)(mode))
+#define Vnext(mask,mode) \
+ (long)trap_14_wll((short)0x47,(long)(mask),(long)(mode))
+#define Vvalid(handle) \
+ (long)trap_14_ww((short)0x48,(short)(handle))
+#define Vload() \
+ (long)trap_14_w((short)0x49)
+#define Vsave() \
+ (long)trap_14_w((short)0x4a)
+#define Vopen() \
+ (long)trap_14_w((short)0x4b)
+#define Vclose() \
+ (long)trap_14_w((short)0x4c)
+#define Vscroll(scrollmode) \
+ (long)trap_14_ww((short)0x4d,(short)(scrollmode))
+#define Voffset() \
+ (long)trap_14_w((short)0x4e)
+#define Vseek() \
+ (long)trap_14_w((short)0x4f)
+#define Vlock(cmd) \
+ (long)trap_14_ww((short)0x50,(short)(cmd))
+#define SetMon(montype) \
+ (long)trap_14_ww((short)0x51,(short)(montype))
+#define MultiMon(cmd) \
+ (long)trap_14_ww((short)0x52,(short)(cmd))
+#define VSizeComp() \
+ (long)trap_14_w((short)0x53)
+#define Vsize(mode) \
+ (long)trap_14_wl((short)0x54,(long)(mode))
+
+/*--- Functions prototypes ---*/
+
+int SDL_XBIOS_ListCentscreenModes(_THIS, int actually_add);
+void SDL_XBIOS_CentscreenSetmode(_THIS, int width, int height, int planes);
+void SDL_XBIOS_CentscreenRestore(_THIS, int prev_handle);
+
+#endif /* _SDL_xbios_centscreen_h */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.c
new file mode 100644
index 0000000..a99ee18
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.c
@@ -0,0 +1,106 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Milan Xbios video functions
+
+ Patrice Mandin
+*/
+
+#include <mint/cookie.h>
+#include <mint/falcon.h>
+
+#include "SDL_xbios.h"
+#include "SDL_xbios_milan.h"
+
+#define NUM_PREDEFINED_MODES 7
+
+typedef struct {
+ Uint16 width, height;
+} predefined_mode_t;
+
+static const predefined_mode_t mode_list[NUM_PREDEFINED_MODES]={
+ {640,400},
+ {640,480},
+ {800,608},
+ {1024,768},
+ {1152,864},
+ {1280,1024},
+ {1600,1200}
+};
+
+static const Uint8 mode_bpp[4]={
+ 8, 15, 16, 32
+};
+
+/*--- Variables ---*/
+
+static int enum_actually_add;
+static SDL_VideoDevice *enum_this;
+
+/*--- Functions ---*/
+
+static unsigned long /*cdecl*/ enumfunc(SCREENINFO *inf, unsigned long flag)
+{
+ xbiosmode_t modeinfo;
+
+ modeinfo.number = inf->devID;
+ modeinfo.width = inf->scrWidth;
+ modeinfo.height = inf->scrHeight;
+ modeinfo.depth = inf->scrPlanes;
+ modeinfo.flags = 0;
+
+ SDL_XBIOS_AddMode(enum_this, enum_actually_add, &modeinfo);
+
+ return ENUMMODE_CONT;
+}
+
+void SDL_XBIOS_ListMilanModes(_THIS, int actually_add)
+{
+ int i;
+
+ /* Read validated predefined modes */
+ for (i=0; i<NUM_PREDEFINED_MODES; i++) {
+ int j;
+ Uint16 deviceid = 0x1000 + (i<<4);
+
+ for (j=1; j<4; j++) {
+ if (Validmode(deviceid + j)) {
+ xbiosmode_t modeinfo;
+
+ modeinfo.number = deviceid + j;
+ modeinfo.width = mode_list[i].width;
+ modeinfo.height = mode_list[i].height;
+ modeinfo.depth = mode_bpp[j-1];
+ modeinfo.flags = 0;
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+ }
+ }
+ }
+
+ /* Read custom created modes */
+ enum_this = this;
+ enum_actually_add = actually_add;
+ VsetScreen(-1, &enumfunc, MI_MAGIC, CMD_ENUMMODES);
+}
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.h
new file mode 100644
index 0000000..bcf5c8a
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_milan.h
@@ -0,0 +1,129 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Milan Xbios video functions
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_xbios_milan_h
+#define _SDL_xbios_milan_h
+
+#include "SDL_xbios.h"
+
+/*--- Defines ---*/
+
+/* Vsetscreen() parameters */
+#define MI_MAGIC 0x4D49
+
+enum {
+ CMD_GETMODE=0,
+ CMD_SETMODE,
+ CMD_GETINFO,
+ CMD_ALLOCPAGE,
+ CMD_FREEPAGE,
+ CMD_FLIPPAGE,
+ CMD_ALLOCMEM,
+ CMD_FREEMEM,
+ CMD_SETADR,
+ CMD_ENUMMODES
+};
+
+enum {
+ ENUMMODE_EXIT=0,
+ ENUMMODE_CONT
+};
+
+enum {
+ BLK_ERR=0,
+ BLK_OK,
+ BLK_CLEARED
+};
+
+/* scrFlags */
+#define SCRINFO_OK 1
+
+/* scrClut */
+#define NO_CLUT 0
+#define HARD_CLUT 1
+#define SOFT_CLUT 2
+
+/* scrFormat */
+#define INTERLEAVE_PLANES 0
+#define STANDARD_PLANES 1
+#define PACKEDPIX_PLANES 2
+
+/* bitFlags */
+#define STANDARD_BITS 1
+#define FALCON_BITS 2
+#define INTEL_BITS 8
+
+/*--- Structures ---*/
+
+typedef struct _scrblk {
+ unsigned long size; /* size of strukture */
+ unsigned long blk_status; /* status bits of blk */
+ unsigned long blk_start; /* Start Adress */
+ unsigned long blk_len; /* length of memblk */
+ unsigned long blk_x; /* x pos in total screen*/
+ unsigned long blk_y; /* y pos in total screen */
+ unsigned long blk_w; /* width */
+ unsigned long blk_h; /* height */
+ unsigned long blk_wrap; /* width in bytes */
+} SCRMEMBLK;
+
+typedef struct screeninfo {
+ unsigned long size; /* Size of structure */
+ unsigned long devID; /* device id number */
+ unsigned char name[64]; /* Friendly name of Screen */
+ unsigned long scrFlags; /* some Flags */
+ unsigned long frameadr; /* Adress of framebuffer */
+ unsigned long scrHeight; /* visible X res */
+ unsigned long scrWidth; /* visible Y res */
+ unsigned long virtHeight; /* virtual X res */
+ unsigned long virtWidth; /* virtual Y res */
+ unsigned long scrPlanes; /* color Planes */
+ unsigned long scrColors; /* # of colors */
+ unsigned long lineWrap; /* # of Bytes to next line */
+ unsigned long planeWarp; /* # of Bytes to next plane */
+ unsigned long scrFormat; /* screen Format */
+ unsigned long scrClut; /* type of clut */
+ unsigned long redBits; /* Mask of Red Bits */
+ unsigned long greenBits; /* Mask of Green Bits */
+ unsigned long blueBits; /* Mask of Blue Bits */
+ unsigned long alphaBits; /* Mask of Alpha Bits */
+ unsigned long genlockBits;/* Mask of Genlock Bits */
+ unsigned long unusedBits; /* Mask of unused Bits */
+ unsigned long bitFlags; /* Bits organisation flags */
+ unsigned long maxmem; /* max. memory in this mode */
+ unsigned long pagemem; /* needed memory for one page */
+ unsigned long max_x; /* max. possible width */
+ unsigned long max_y; /* max. possible heigth */
+} SCREENINFO;
+
+/*--- Functions prototypes ---*/
+
+void SDL_XBIOS_ListMilanModes(_THIS, int actually_add);
+
+#endif /* _SDL_xbios_milan_h */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.c
new file mode 100644
index 0000000..8b0ed2c
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.c
@@ -0,0 +1,83 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ ScreenBlaster 3 functions
+
+ Patrice Mandin
+*/
+
+/*--- Includes ---*/
+
+#include "SDL_stdinc.h"
+#include "SDL_xbios.h"
+#include "SDL_xbios_sb3.h"
+
+/*--- Defines ---*/
+
+const int SDL_XBIOS_scpn_planes_device[]={
+ SCPN_DEV_1BPP,
+ SCPN_DEV_4BPP,
+ SCPN_DEV_8BPP,
+ SCPN_DEV_16BPP,
+ SCPN_DEV_2BPP,
+ SCPN_DEV_4BPP,
+ SCPN_DEV_1BPP
+};
+
+/*--- Functions ---*/
+
+int SDL_XBIOS_SB3Usable(scpn_cookie_t *cookie_scpn)
+{
+ scpn_screeninfo_t *scrinfo;
+ int bpp;
+
+ /* Check if current SB3 mode is usable, i.e. 8 or 16bpp */
+ scrinfo = cookie_scpn->screen_info;
+ bpp = 1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]);
+
+ if ((bpp==8) || (bpp==16)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void SDL_XBIOS_ListSB3Modes(_THIS, int actually_add, scpn_cookie_t *cookie_scpn)
+{
+ scpn_screeninfo_t *scrinfo;
+ xbiosmode_t modeinfo;
+
+ scrinfo = cookie_scpn->screen_info;
+ if (actually_add) {
+ scrinfo->h_pos = scrinfo->v_pos = 0;
+ }
+
+ modeinfo.number = -1;
+ modeinfo.width = scrinfo->virtual_width;
+ modeinfo.height = scrinfo->virtual_height;
+ modeinfo.depth = 1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]);
+ modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+
+ SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+}
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.h
new file mode 100644
index 0000000..3272c31
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_sb3.h
@@ -0,0 +1,82 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ ScreenBlaster 3 definitions
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_xbios_sb3_h_
+#define _SDL_xbios_sb3_h_
+
+/*--- Defines ---*/
+
+#ifndef C_SCPN
+#define C_SCPN 0x5343504EL
+#endif
+
+#define SCPN_DEV_1BPP 0
+#define SCPN_DEV_2BPP 1
+#define SCPN_DEV_4BPP 2
+#define SCPN_DEV_8BPP 3
+#define SCPN_DEV_16BPP 4
+
+extern const int SDL_XBIOS_scpn_planes_device[];
+
+/*--- Types ---*/
+
+typedef struct {
+ unsigned short virtual_width; /* Virtual screen width */
+ unsigned short virtual_height; /* Virtual screen height */
+ unsigned short visible_width; /* Visible width */
+ unsigned short visible_height; /* Visible height */
+ unsigned short h_pos; /* Horizontal position in virtual screen */
+ unsigned short v_pos; /* Vertical position in virtual screen */
+ unsigned short dummy;
+ unsigned long size; /* Size of screen in bytes */
+ unsigned short device; /* Device number to find planes = getRez() */
+ /* = Index in scpn_planes_device[] */
+} scpn_screeninfo_t;
+
+typedef struct {
+ unsigned long magic; /* just a BRA assembler jump */
+ unsigned short version;
+ void *dummy1;
+ unsigned short ptsout0_1;
+ unsigned short ptsout0_2;
+ unsigned short dummy3;
+ unsigned char date[8]; /* Date of program build */
+ unsigned char asm_string[30]; /* 10 times the 'ASM' string */
+ unsigned short dummy4;
+ scpn_screeninfo_t *screen_info;
+ unsigned short dummy6;
+} scpn_cookie_t;
+
+/*--- Function prototypes ---*/
+
+int SDL_XBIOS_SB3Usable(scpn_cookie_t *cookie_scpn);
+
+void SDL_XBIOS_ListSB3Modes(_THIS, int actually_add, scpn_cookie_t *cookie_scpn);
+
+#endif /* _SDL_xbios_sb3_h_ */
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.c b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.c
new file mode 100644
index 0000000..b0f8499
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.c
@@ -0,0 +1,63 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Turbo veille screensaver
+
+ Patrice Mandin
+*/
+
+#include <mint/cookie.h>
+
+#include "SDL_xbios.h"
+#include "SDL_xbios_tveille.h"
+
+static tveille_t *cookie_veil = NULL;
+static int status;
+
+int SDL_XBIOS_TveillePresent(_THIS)
+{
+ long dummy;
+
+ cookie_veil = NULL;
+ if (Getcookie(C_VeiL, &dummy) == C_FOUND) {
+ cookie_veil = (tveille_t *) dummy;
+ }
+
+ return (cookie_veil != NULL);
+}
+
+void SDL_XBIOS_TveilleDisable(_THIS)
+{
+ if (cookie_veil) {
+ status = cookie_veil->enabled;
+ cookie_veil->enabled = 0xff;
+ }
+}
+
+void SDL_XBIOS_TveilleEnable(_THIS)
+{
+ if (cookie_veil) {
+ cookie_veil->enabled = status;
+ }
+}
diff --git a/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.h b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.h
new file mode 100644
index 0000000..8a9cd7d
--- /dev/null
+++ b/distrib/sdl-1.2.15/src/video/xbios/SDL_xbios_tveille.h
@@ -0,0 +1,64 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2012 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"
+
+/*
+ Turbo veille screensaver
+
+ Patrice Mandin
+*/
+
+#ifndef _SDL_xbios_tveille_h
+#define _SDL_xbios_tveille_h
+
+#include "SDL_xbios.h"
+
+/*--- Structures ---*/
+
+typedef struct {
+ unsigned long version;
+ void (*prg_ptr)();
+ void (*kbd_ptr)();
+ void (*vbl_ptr)();
+ unsigned long vbl_count;
+ void (*oldkbd_ptr)();
+ unsigned long off_count;
+ unsigned long prg_size;
+ unsigned long dummy1[4];
+ unsigned char dummy2;
+ unsigned char status;
+ unsigned short freq;
+ unsigned short dummy3;
+ unsigned char clear_first;
+ unsigned char enabled; /* 0=enabled, 0xff=disabled */
+ unsigned char serial_redir;
+ unsigned char dummy4;
+ void (*oldserial_ptr)();
+} tveille_t;
+
+/*--- Functions prototypes ---*/
+
+int SDL_XBIOS_TveillePresent(_THIS);
+void SDL_XBIOS_TveilleDisable(_THIS);
+void SDL_XBIOS_TveilleEnable(_THIS);
+
+#endif /* _SDL_xbios_tveille_h */